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

    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

 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. 配置文件中配置自定义工厂类:

<!-- 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. 测试类

 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 自定义工厂类
 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 private static class LCRRepositoryFactory<S extends BaseDomain, ID extends Serializable> extends MongoRepositoryFactory {  
30         private final MongoOperations mongoOperations;  
31   
32         public LCRRepositoryFactory(MongoOperations mongoOperations) {  
33             super(mongoOperations);  
34             this.mongoOperations = mongoOperations;  
35         }  
36   
37         protected Object getTargetRepository(RepositoryMetadata metadata) {  
38             Class<?> repositoryInterface = metadata.getRepositoryInterface();  
39             MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());  
40             if (isQueryDslRepository(repositoryInterface)) {  
41                 return new QueryDslMongoRepository(entityInformation, mongoOperations);  
42             } else {  
43                 return new BaseRepositoryImpl((MongoEntityInformation<S, ID>) entityInformation, this.mongoOperations);  
44             }  
45         }  
46   
47         private static boolean isQueryDslRepository(Class<?> repositoryInterface) {  
48             return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);  
49         }  
50   
51         protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {  
52             return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class  
53                     : BaseRepositoryImpl.class;  
54         }  
55     }  
56 }  

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();  
    }  

3 自定义接口实现

 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   @Override  
34     public Items<T> list(ListParam<T> listParam) {  
35         Criteria criteria = buildCriteria(listParam);  
36         Query query = new Query(criteria)  
37                 .with(listParam)  
38                 .skip(listParam.getOffset())  
39                 .limit(listParam.getLimit());  
40         List<T> list = mongoOperations.find(query, entityInformation.getJavaType());  
41         if (listParam.isCount()) {  
42             long count = mongoOperations.count(new Query(criteria), entityInformation.getJavaType());  
43             return Items.of(list, count);  
44         }  
45         return Items.of(list);  
46     }  
47   
48     private Criteria buildCriteria(ListParam<T> listParam) {  
49         List<Condition> conditions = listParam.getConditions();  
50         if (conditions.isEmpty()) {  
51             return new Criteria();  
52         }  
53         int conditionSize = conditions.size();  
54         Criteria criteria = buildCriteria(conditions.get(0));  
55         if (conditionSize > 1) {  
56             Criteria[] otherCriteria = new Criteria[conditionSize - 1];  
57             for (int i = 1; i < conditionSize; i++) {  
58                 otherCriteria[i - 1] = buildCriteria(conditions.get(i));  
59             }  
60             criteria.andOperator(otherCriteria);  
61         }  
62         return criteria;  
63     }  
64    private Criteria buildCriteria(Condition condition) {  
65         Criteria criteria = Criteria.where(condition.getField());  
66         Object value = condition.getValue();  
67         switch (condition.getOperator()) {  
68             case EQ:  
69                 criteria = criteria.is(value);  
70                 break;  
71             case NE:  
72                 criteria = criteria.ne(value);  
73                 break;  
74             case GT:  
75                 criteria = criteria.gt(value);  
76                 break;  
77             case GE:  
78                 criteria = criteria.gte(value);  
79                 break;  
80             case LT:  
81                 criteria = criteria.lt(value);  
82                 break;  
83             case LE:  
84                 criteria = criteria.lte(value);  
85                 break;  
86             case LIKE:  
87                 value = value.toString().replaceAll("%", ".*").replaceAll("_", ".");  
88                 criteria = criteria.regex(value.toString());  
89                 break;  
90             default:  
91                 throw MyBizException.of(ErrorCode.INVALID_QUERY, "非法或不支持的操作符");  
92         }  
93         return criteria;  
94     }  
95   
96 }  

4 配置

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     }  

 

 

posted @ 2016-10-29 15:11  yweihainan  阅读(1874)  评论(0编辑  收藏  举报