1 spring data jpa
雖然說spring data 提供了很多DAO 接口,但是依然可能不能滿足我們日常的使用,所以,有時我們需要自定義接口方法。自定義接口方法步驟如下:
1. 創建自定義工廠類:CustomerJpaRepositoryFactoryBean, 需要繼承JpaRepositoryFactoryBean
- package org.zgf.spring.data.customer;
- import java.io.Serializable;
- import javax.persistence.EntityManager;
- import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
- import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
- import org.springframework.data.repository.Repository;
- import org.springframework.data.repository.core.RepositoryMetadata;
- import org.springframework.data.repository.core.support.RepositoryFactorySupport;
- /**
- * 自定義工廠
- * @author: zonggf
- * @date: 2016年1月18日-下午2:16:18
- */
- public class CustomerJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
- extends JpaRepositoryFactoryBean<T, S, ID> {
- @Override
- protected RepositoryFactorySupport createRepositoryFactory(
- EntityManager entityManager) {
- return new CustomerRepositoryFactory(entityManager);
- }
- private static class CustomerRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
- private EntityManager entityManager;
- public CustomerRepositoryFactory(EntityManager entityManager) {
- super(entityManager);
- this.entityManager = entityManager;
- }
- protected Object getTargetRepository(RepositoryMetadata metadata) {
- return new IBaseDaoImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
- }
- protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
- return IBaseDao.class;
- }
- }
- }
2. 創建自定義接口:IBaseDao, 需要繼承JpaRepository
- package org.zgf.spring.data.customer;
- import java.io.Serializable;
- import org.springframework.data.jpa.repository.JpaRepository;
- import org.springframework.data.repository.NoRepositoryBean;
- //必須使用該註解標明,此接口不是一個Repository Bean
- @NoRepositoryBean
- public interface IBaseDao <T, ID extends Serializable> extends JpaRepository<T, ID>{
- //自定義接口方法
- public void sayHello(String name);
- }
3. 創建自定義接口實現 類:IBaseDaoImpl, 名稱必須是 接口名+ Impl
- package org.zgf.spring.data.customer;
- import java.io.Serializable;
- import javax.persistence.EntityManager;
- import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
- import org.springframework.data.repository.NoRepositoryBean;
- //必須使用該註解標明,此接口不是一個Repository Bean
- @NoRepositoryBean
- public class IBaseDaoImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
- implements IBaseDao<T, ID> {
- private EntityManager entityManager;
- public IBaseDaoImpl(Class<T> domainClass, EntityManager em) {
- super(domainClass, em);
- this.entityManager = em;
- }
- @Override
- public void sayHello(String name) {
- System.out.println("entityManage:" + entityManager);
- System.out.println("hello, " + name);
- }
- }
4. 配置文件中配置自定義工廠類:
- !-- 5. 配置 SpringData -->
- <!-- 加入 jpa 的命名空間 掃描 Repository Bean 所在的 package, 自定義工廠類 -->
- <jpa:repositories base-package="org.zgf.spring.data" entity-manager-factory-ref="entityManagerFactory" factory-class="org.zgf.spring.data.customer.CustomerJpaRepositoryFactoryBean"/>
5. 測試類
- package org.zgf.spring.data.customer;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.test.context.ContextConfiguration;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- import org.springframework.test.context.transaction.TransactionConfiguration;
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = { "classpath*:/applicationContext-customer-jpa.xml" })
- @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
- public class Test_CustomerStudentDao {
- @Autowired
- private StudentBaseDao studentDao;
- @Test
- public void test(){
- this.studentDao.sayHello("zong");
- }
- }
2 spring data mongo
1 自定義工廠類
- import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;
- import java.io.Serializable;
- import org.springframework.data.mongodb.core.MongoOperations;
- import org.springframework.data.mongodb.repository.MongoRepository;
- import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
- import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;
- import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
- import org.springframework.data.mongodb.repository.support.QueryDslMongoRepository;
- import org.springframework.data.querydsl.QueryDslPredicateExecutor;
- import org.springframework.data.repository.core.RepositoryMetadata;
- import org.springframework.data.repository.core.support.RepositoryFactorySupport;
- import com.jt.zjy.base.domain.BaseDomain;
- import com.jt.zjy.base.repository.impl.BaseRepositoryImpl;
- /**
- * 用於生成自擴展的Repository方法,比如softDelete
- * Created by weihainan on 2016/8/5.
- */
- public class CustomMongoRepositoryFactoryBean<T extends MongoRepository<S, ID>, S extends BaseDomain, ID extends Serializable>
- extends MongoRepositoryFactoryBean<T, S, ID> {
- @Override
- protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
- return new LCRRepositoryFactory(operations);
- }
- private static class LCRRepositoryFactory<S extends BaseDomain, ID extends Serializable> extends MongoRepositoryFactory {
- private final MongoOperations mongoOperations;
- public LCRRepositoryFactory(MongoOperations mongoOperations) {
- super(mongoOperations);
- this.mongoOperations = mongoOperations;
- }
- protected Object getTargetRepository(RepositoryMetadata metadata) {
- Class<?> repositoryInterface = metadata.getRepositoryInterface();
- MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
- if (isQueryDslRepository(repositoryInterface)) {
- return new QueryDslMongoRepository(entityInformation, mongoOperations);
- } else {
- return new BaseRepositoryImpl((MongoEntityInformation<S, ID>) entityInformation, this.mongoOperations);
- }
- }
- private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
- return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
- }
- protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
- return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class
- : BaseRepositoryImpl.class;
- }
- }
- }
2 自定義接口
- import com.jt.zjy.base.domain.BaseDomain;
- import com.jt.zjy.base.list.Items;
- import com.jt.zjy.base.list.ListParam;
- import org.springframework.data.repository.NoRepositoryBean;
- import org.springframework.data.repository.PagingAndSortingRepository;
- import java.io.Serializable;
- import java.util.List;
- /**
- * Created by WeiHaiNan on 2016/1/5.
- */
- @NoRepositoryBean
- public interface BaseRepository<T extends BaseDomain<I>, I extends Serializable> extends PagingAndSortingRepository<T, I> {
- Items<T> list(ListParam<T> listParam);
- @Override
- List<T> findAll();
- }
- import java.io.Serializable;
- import java.util.List;
- import org.springframework.data.mongodb.core.MongoOperations;
- import org.springframework.data.mongodb.core.query.Criteria;
- import org.springframework.data.mongodb.core.query.Query;
- import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
- import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
- import com.jt.zjy.base.domain.BaseDomain;
- import com.jt.zjy.base.exception.ErrorCode;
- import com.jt.zjy.base.exception.MyBizException;
- import com.jt.zjy.base.list.Condition;
- import com.jt.zjy.base.list.Items;
- import com.jt.zjy.base.list.ListParam;
- import com.jt.zjy.base.repository.BaseRepository;
- /**
- * Dao基礎實現
- * Created by WeiHaiNan on 2016/9/12.
- */
- public class BaseRepositoryImpl<T extends BaseDomain<I>, I extends Serializable> extends SimpleMongoRepository<T, I>
- implements BaseRepository<T, I> {
- private final MongoOperations mongoOperations;
- private final MongoEntityInformation<T, I> entityInformation;
- public BaseRepositoryImpl(MongoEntityInformation<T, I> metadata, MongoOperations mongoOperations) {
- super(metadata, mongoOperations);
- this.entityInformation = metadata;
- this.mongoOperations = mongoOperations;
- }
- @Override
- public Items<T> list(ListParam<T> listParam) {
- Criteria criteria = buildCriteria(listParam);
- Query query = new Query(criteria)
- .with(listParam)
- .skip(listParam.getOffset())
- .limit(listParam.getLimit());
- List<T> list = mongoOperations.find(query, entityInformation.getJavaType());
- if (listParam.isCount()) {
- long count = mongoOperations.count(new Query(criteria), entityInformation.getJavaType());
- return Items.of(list, count);
- }
- return Items.of(list);
- }
- private Criteria buildCriteria(ListParam<T> listParam) {
- List<Condition> conditions = listParam.getConditions();
- if (conditions.isEmpty()) {
- return new Criteria();
- }
- int conditionSize = conditions.size();
- Criteria criteria = buildCriteria(conditions.get(0));
- if (conditionSize > 1) {
- Criteria[] otherCriteria = new Criteria[conditionSize - 1];
- for (int i = 1; i < conditionSize; i++) {
- otherCriteria[i - 1] = buildCriteria(conditions.get(i));
- }
- criteria.andOperator(otherCriteria);
- }
- return criteria;
- }
- private Criteria buildCriteria(Condition condition) {
- Criteria criteria = Criteria.where(condition.getField());
- Object value = condition.getValue();
- switch (condition.getOperator()) {
- case EQ:
- criteria = criteria.is(value);
- break;
- case NE:
- criteria = criteria.ne(value);
- break;
- case GT:
- criteria = criteria.gt(value);
- break;
- case GE:
- criteria = criteria.gte(value);
- break;
- case LT:
- criteria = criteria.lt(value);
- break;
- case LE:
- criteria = criteria.lte(value);
- break;
- case LIKE:
- value = value.toString().replaceAll("%", ".*").replaceAll("_", ".");
- criteria = criteria.regex(value.toString());
- break;
- default:
- throw MyBizException.of(ErrorCode.INVALID_QUERY, "非法或不支持的操作符");
- }
- return criteria;
- }
- }
4 配置
- @EnableMongoRepositories(
- basePackages = "com.jt",
- includeFilters = @ComponentScan.Filter(Repository.class),
- basePackageClasses = BaseRepositoryImpl.class,
- repositoryFactoryBeanClass = CustomMongoRepositoryFactoryBean.class
- )
- public class MongoConfigurerAdapter extends AbstractMongoConfigurerAdapter {
- }