spring data 自定義接口

1 spring data jpa


雖然說spring data 提供了很多DAO 接口,但是依然可能不能滿足我們日常的使用,所以,有時我們需要自定義接口方法。自定義接口方法步驟如下:

1.  創建自定義工廠類:CustomerJpaRepositoryFactoryBean, 需要繼承JpaRepositoryFactoryBean

  1. package org.zgf.spring.data.customer;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import javax.persistence.EntityManager;  
  6.   
  7. import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;  
  8. import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;  
  9. import org.springframework.data.repository.Repository;  
  10. import org.springframework.data.repository.core.RepositoryMetadata;  
  11. import org.springframework.data.repository.core.support.RepositoryFactorySupport;  
  12.   
  13. /** 
  14.  *  自定義工廠 
  15.  * @author: zonggf 
  16.  * @date: 2016年1月18日-下午2:16:18 
  17.  */  
  18. public class CustomerJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>  
  19.         extends JpaRepositoryFactoryBean<T, S, ID> {  
  20.   
  21.     @Override  
  22.     protected RepositoryFactorySupport createRepositoryFactory(  
  23.             EntityManager entityManager) {  
  24.         return new CustomerRepositoryFactory(entityManager);  
  25.     }  
  26.   
  27.     private static class CustomerRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {  
  28.   
  29.         private EntityManager entityManager;  
  30.   
  31.         public CustomerRepositoryFactory(EntityManager entityManager) {  
  32.             super(entityManager);  
  33.             this.entityManager = entityManager;  
  34.         }  
  35.   
  36.         protected Object getTargetRepository(RepositoryMetadata metadata) {  
  37.             return new IBaseDaoImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);  
  38.         }  
  39.   
  40.         protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {  
  41.             return IBaseDao.class;  
  42.         }  
  43.     }  
  44. }  

2. 創建自定義接口:IBaseDao, 需要繼承JpaRepository
  1. package org.zgf.spring.data.customer;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.springframework.data.jpa.repository.JpaRepository;  
  6. import org.springframework.data.repository.NoRepositoryBean;  
  7.   
  8. //必須使用該註解標明,此接口不是一個Repository Bean  
  9. @NoRepositoryBean  
  10. public interface IBaseDao <T, ID extends Serializable> extends JpaRepository<T, ID>{  
  11.   
  12.     //自定義接口方法  
  13.     public void sayHello(String name);  
  14.       
  15. }  

3. 創建自定義接口實現 類:IBaseDaoImpl, 名稱必須是 接口名+ Impl
  1. package org.zgf.spring.data.customer;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import javax.persistence.EntityManager;  
  6.   
  7. import org.springframework.data.jpa.repository.support.SimpleJpaRepository;  
  8. import org.springframework.data.repository.NoRepositoryBean;  
  9. //必須使用該註解標明,此接口不是一個Repository Bean  
  10. @NoRepositoryBean  
  11. public class IBaseDaoImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>  
  12.         implements IBaseDao<T, ID> {  
  13.       
  14.     private EntityManager entityManager;  
  15.   
  16.     public IBaseDaoImpl(Class<T> domainClass, EntityManager em) {  
  17.         super(domainClass, em);  
  18.         this.entityManager = em;  
  19.     }  
  20.   
  21.     @Override  
  22.     public void sayHello(String name) {  
  23.         System.out.println("entityManage:" + entityManager);  
  24.         System.out.println("hello, " + name);  
  25.     }  
  26. }  

4. 配置文件中配置自定義工廠類:

  1. !-- 5. 配置 SpringData -->  
  2. <!-- 加入  jpa 的命名空間   掃描 Repository Bean 所在的 package, 自定義工廠類 -->  
  3. <jpa:repositories base-package="org.zgf.spring.data" entity-manager-factory-ref="entityManagerFactory" factory-class="org.zgf.spring.data.customer.CustomerJpaRepositoryFactoryBean"/>  

5. 測試類
  1. package org.zgf.spring.data.customer;  
  2.   
  3. import org.junit.Test;  
  4. import org.junit.runner.RunWith;  
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.test.context.ContextConfiguration;  
  7. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
  8. import org.springframework.test.context.transaction.TransactionConfiguration;  
  9.   
  10. @RunWith(SpringJUnit4ClassRunner.class)  
  11. @ContextConfiguration(locations = { "classpath*:/applicationContext-customer-jpa.xml" })  
  12. @TransactionConfiguration(transactionManager = "transactionManager"defaultRollback = false)  
  13. public class Test_CustomerStudentDao {  
  14.       
  15.     @Autowired   
  16.     private StudentBaseDao studentDao;  
  17.   
  18.     @Test  
  19.     public void test(){  
  20.         this.studentDao.sayHello("zong");  
  21.     }  
  22. }

2 spring data mongo


1 自定義工廠類

[java] view plain copy
  1. import static org.springframework.data.querydsl.QueryDslUtils.QUERY_DSL_PRESENT;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.springframework.data.mongodb.core.MongoOperations;  
  6. import org.springframework.data.mongodb.repository.MongoRepository;  
  7. import org.springframework.data.mongodb.repository.query.MongoEntityInformation;  
  8. import org.springframework.data.mongodb.repository.support.MongoRepositoryFactory;  
  9. import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;  
  10. import org.springframework.data.mongodb.repository.support.QueryDslMongoRepository;  
  11. import org.springframework.data.querydsl.QueryDslPredicateExecutor;  
  12. import org.springframework.data.repository.core.RepositoryMetadata;  
  13. import org.springframework.data.repository.core.support.RepositoryFactorySupport;  
  14.   
  15. import com.jt.zjy.base.domain.BaseDomain;  
  16. import com.jt.zjy.base.repository.impl.BaseRepositoryImpl;  
  17.   
  18. /** 
  19.  * 用於生成自擴展的Repository方法,比如softDelete 
  20.  * Created by weihainan on 2016/8/5. 
  21.  */  
  22. public class CustomMongoRepositoryFactoryBean<T extends MongoRepository<S, ID>, S extends BaseDomain, ID extends Serializable>  
  23.         extends MongoRepositoryFactoryBean<T, S, ID> {  
  24.   
  25.     @Override  
  26.     protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {  
  27.         return new LCRRepositoryFactory(operations);  
  28.     }  
  29.   
  30.     private static class LCRRepositoryFactory<S extends BaseDomain, ID extends Serializable> extends MongoRepositoryFactory {  
  31.         private final MongoOperations mongoOperations;  
  32.   
  33.         public LCRRepositoryFactory(MongoOperations mongoOperations) {  
  34.             super(mongoOperations);  
  35.             this.mongoOperations = mongoOperations;  
  36.         }  
  37.   
  38.         protected Object getTargetRepository(RepositoryMetadata metadata) {  
  39.             Class<?> repositoryInterface = metadata.getRepositoryInterface();  
  40.             MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());  
  41.             if (isQueryDslRepository(repositoryInterface)) {  
  42.                 return new QueryDslMongoRepository(entityInformation, mongoOperations);  
  43.             } else {  
  44.                 return new BaseRepositoryImpl((MongoEntityInformation<S, ID>) entityInformation, this.mongoOperations);  
  45.             }  
  46.         }  
  47.   
  48.         private static boolean isQueryDslRepository(Class<?> repositoryInterface) {  
  49.             return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);  
  50.         }  
  51.   
  52.         protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {  
  53.             return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class  
  54.                     : BaseRepositoryImpl.class;  
  55.         }  
  56.     }  
  57. }  

2 自定義接口

[java] view plain copy
  1. import com.jt.zjy.base.domain.BaseDomain;  
  2. import com.jt.zjy.base.list.Items;  
  3. import com.jt.zjy.base.list.ListParam;  
  4. import org.springframework.data.repository.NoRepositoryBean;  
  5. import org.springframework.data.repository.PagingAndSortingRepository;  
  6.   
  7. import java.io.Serializable;  
  8. import java.util.List;  
  9.   
  10. /** 
  11.  * Created by WeiHaiNan on 2016/1/5. 
  12.  */  
  13. @NoRepositoryBean  
  14. public interface BaseRepository<T extends BaseDomain<I>, I extends Serializable> extends PagingAndSortingRepository<T, I> {  
  15.   
  16.     Items<T> list(ListParam<T> listParam);  
  17.   
  18.     @Override  
  19.     List<T> findAll();  
  20. }  

3 自定義接口實現

[java] view plain copy
  1. import java.io.Serializable;  
  2. import java.util.List;  
  3.   
  4. import org.springframework.data.mongodb.core.MongoOperations;  
  5. import org.springframework.data.mongodb.core.query.Criteria;  
  6. import org.springframework.data.mongodb.core.query.Query;  
  7. import org.springframework.data.mongodb.repository.query.MongoEntityInformation;  
  8. import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;  
  9.   
  10. import com.jt.zjy.base.domain.BaseDomain;  
  11. import com.jt.zjy.base.exception.ErrorCode;  
  12. import com.jt.zjy.base.exception.MyBizException;  
  13. import com.jt.zjy.base.list.Condition;  
  14. import com.jt.zjy.base.list.Items;  
  15. import com.jt.zjy.base.list.ListParam;  
  16. import com.jt.zjy.base.repository.BaseRepository;  
  17.   
  18. /** 
  19.  * Dao基礎實現 
  20.  * Created by WeiHaiNan on 2016/9/12. 
  21.  */  
  22. public class BaseRepositoryImpl<T extends BaseDomain<I>, I extends Serializable> extends SimpleMongoRepository<T, I>  
  23.    implements BaseRepository<T, I> {  
  24.       
  25.     private final MongoOperations mongoOperations;  
  26.     private final MongoEntityInformation<T, I> entityInformation;  
  27.   
  28.     public BaseRepositoryImpl(MongoEntityInformation<T, I> metadata, MongoOperations mongoOperations) {  
  29.         super(metadata, mongoOperations);  
  30.         this.entityInformation = metadata;  
  31.         this.mongoOperations = mongoOperations;  
  32.     }  
  33.   
  34.     @Override  
  35.     public Items<T> list(ListParam<T> listParam) {  
  36.         Criteria criteria = buildCriteria(listParam);  
  37.         Query query = new Query(criteria)  
  38.                 .with(listParam)  
  39.                 .skip(listParam.getOffset())  
  40.                 .limit(listParam.getLimit());  
  41.         List<T> list = mongoOperations.find(query, entityInformation.getJavaType());  
  42.         if (listParam.isCount()) {  
  43.             long count = mongoOperations.count(new Query(criteria), entityInformation.getJavaType());  
  44.             return Items.of(list, count);  
  45.         }  
  46.         return Items.of(list);  
  47.     }  
  48.   
  49.     private Criteria buildCriteria(ListParam<T> listParam) {  
  50.         List<Condition> conditions = listParam.getConditions();  
  51.         if (conditions.isEmpty()) {  
  52.             return new Criteria();  
  53.         }  
  54.         int conditionSize = conditions.size();  
  55.         Criteria criteria = buildCriteria(conditions.get(0));  
  56.         if (conditionSize > 1) {  
  57.             Criteria[] otherCriteria = new Criteria[conditionSize - 1];  
  58.             for (int i = 1; i < conditionSize; i++) {  
  59.                 otherCriteria[i - 1] = buildCriteria(conditions.get(i));  
  60.             }  
  61.             criteria.andOperator(otherCriteria);  
  62.         }  
  63.         return criteria;  
  64.     }  
  65.   
  66.     private Criteria buildCriteria(Condition condition) {  
  67.         Criteria criteria = Criteria.where(condition.getField());  
  68.         Object value = condition.getValue();  
  69.         switch (condition.getOperator()) {  
  70.             case EQ:  
  71.                 criteria = criteria.is(value);  
  72.                 break;  
  73.             case NE:  
  74.                 criteria = criteria.ne(value);  
  75.                 break;  
  76.             case GT:  
  77.                 criteria = criteria.gt(value);  
  78.                 break;  
  79.             case GE:  
  80.                 criteria = criteria.gte(value);  
  81.                 break;  
  82.             case LT:  
  83.                 criteria = criteria.lt(value);  
  84.                 break;  
  85.             case LE:  
  86.                 criteria = criteria.lte(value);  
  87.                 break;  
  88.             case LIKE:  
  89.                 value = value.toString().replaceAll("%"".*").replaceAll("_"".");  
  90.                 criteria = criteria.regex(value.toString());  
  91.                 break;  
  92.             default:  
  93.                 throw MyBizException.of(ErrorCode.INVALID_QUERY, "非法或不支持的操作符");  
  94.         }  
  95.         return criteria;  
  96.     }  
  97.   
  98. }  

4 配置

[java] view plain copy
  1. @EnableMongoRepositories(  
  2.         basePackages = "com.jt",  
  3.         includeFilters = @ComponentScan.Filter(Repository.class),  
  4.         basePackageClasses = BaseRepositoryImpl.class,  
  5.         repositoryFactoryBeanClass = CustomMongoRepositoryFactoryBean.class  
  6.        )  
  7. public class MongoConfigurerAdapter extends AbstractMongoConfigurerAdapter {  
  8.   
  9. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章