[SpringBoot实践]spring-data-mongo自定义Repository接口及其实现
来源:互联网 发布:ios 可变字典添加数据 编辑:程序博客网 时间:2024/06/06 23:55
概述
通常我们使用spring-data-mongo时,会让我们的Repository(如UserRepository)继承MongoRepository接口,然后编写业务方法。碰到需要自定义实现代码的时候,就编写UserRepositoryImpl类。不管如何都是非常方便的。
但是有时候的一些方法是需要通用的,比如通过Criteria进行查询(MongoRepository没有相关的方法提供。可能是小弟没有发现,有误的话希望大家可以指出^-^)。
不多说,开始搬砖。
创建项目
说明
这里直接用Spring-boot快速创建项目,pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>dpos-repository</artifactId> <dependencies> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>${scala.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> </dependencies></project>
然后我们定义实体类User
@Documentpublic class User extends BaseEntity{ private String name; private String password; //各种setter,getter}
方案一
编写Repository接口
public interface UserRepository extends MongoRepository<User, String> { /** * * @param criteria * @param pageable * @return */ Page<User> find(Criteria criteria, Pageable pageable);}
然后编写实现类UserRepositoryImpl
public class UserRepositoryImpl{ @Autowired protected MongoTemplate mongoTemplate; /** * @param criteria * @param pageable * @return */ Page<User> find(Criteria criteria, Pageable pageable){ Query query=new Query(criteria); final long total=mongoTemplate.count(query, User.class); final List<User> list=mongoTemplate.find(query.with(pageable), User.class); return new PageImpl<User>(list, pageable, total); }}
最后写一个测试用例看看我们的代码是否正确
public class UserRepoTest extends TestOnSpring{ protected final String password="123456"; final String[] names=new String[]{"张三","李四"}; protected Pageable pageable=new PageRequest(0,10); protected static Logger logger= LoggerFactory.getLogger(UserRepoTest.class); @Autowired private UserRepository userRepo; /** * 插入数据 */ @Before public void init(){ inserTestData(); } private void inserTestData(){ for(String n:names){ User u=new User(); u.setName(n).setPassword(password); userRepo.save(u); logger.info("插入用户:{}",u.toString()); } } @Test public void select(){ List<User> users=userRepo.findAll(); assertThat(users.size(), is(2)); assertThat(users.get(0).getPassword(), is(password)); assertThat(users.get(0).getName(), is(names[0])); } @Test public void findByCriteria(){ Page<User> page=userRepo.find(Criteria.where("password").is(password), pageable); assertThat(page.getTotalElements(), is(2L)); page = userRepo.find(Criteria.where("name").is(names[0]),pageable); assertThat(page.getTotalElements(), is(1L)); assertThat(page.getContent().get(0).getName(), is(names[0])); } @After public void clear(){ logger.info("清空全部的测试数据......"); userRepo.deleteAll(); }}
运行结果:
定义统一接口
现在我想让find(Criteria criteria,Pageable pageable)作为一个统一的方法,即有新的实体需要操作时不需要重复实现。
首先,定义我们的CommonRepository(因为项目是用scala编写,这里贴出来的是scala的实现)
/** * 通用的Repository * Created by zengxm on 2016/4/14 0014. */@NoRepositoryBeantrait CommonRepository[T,ID<:java.io.Serializable] extends MongoRepository[T,ID]{ def find(query:Query, p: Pageable):Page[T] def find(criteria: Criteria, p: Pageable):Page[T]}
注意,要加上@NoRepositoryBean 注解,避免spring扫描CommonRepository。
然后编写实现类
class CommonRepositoryImpl[T, ID<:java.io.Serializable](matedata:MongoEntityInformation[T,ID],mongoOp:MongoOperations) extends SimpleMongoRepository[T,ID](matedata, mongoOp) with CommonRepository[T,ID] { override def find(query: Query, p: Pageable): Page[T] = { val total=mongoOp.count(query, matedata.getJavaType) val list=mongoOp.find(query.`with`(p), matedata.getJavaType) new PageImpl[T](list, p, total) } override def find(criteria: Criteria, p: Pageable): Page[T] = find(new Query(criteria), p)}
附上java版本的实现代码:
public class CommonMongoRepositoryImpl<T, ID extends Serializable> extends SimpleMongoRepository<T,ID> implements CommonRepository<T,ID> { protected final MongoOperations mongoTemplate; protected final MongoEntityInformation<T, ID> entityInformation; public CommonMongoRepositoryImpl(MongoEntityInformation<T, ID> metadata, MongoOperations mongoOperations) { super(metadata, mongoOperations); this.mongoTemplate=mongoOperations; this.entityInformation = metadata; } protected Class<T> getEntityClass(){ return entityInformation.getJavaType(); } @Override public Page<T> find(Query query, Pageable p) { long total=mongoTemplate.count(query, getEntityClass()); List<T> list=mongoTemplate.find(query.with(p), getEntityClass()); return new PageImpl<T>(list, p, total); } @Override public Page<T> find(Criteria criteria, Pageable p) { return find(new Query(criteria), p); }}
最后我们需要告诉Spring使用CommonRepositoryImpl作为默认的Repository实现类。
/** * 配置默认的Repository实现类为CommonRepositoryImpl,代替SimpleMongoRepository * * 同时修改默认的Repository扫描目录为 com.test * Created by zengxm on 2016/4/14 0014. */@Configuration@EnableMongoRepositories(repositoryBaseClass = classOf[CommonRepositoryImpl[_, _]], basePackages = Array("com.test"))class Config {}
然后UserRepository就可以继承CommonRepository了。
重新运行测试用例,结果与方案一一致。至此,功能OK。
2 0
- [SpringBoot实践]spring-data-mongo自定义Repository接口及其实现
- Spring data 接口之 自定义Repository 接口
- Repository接口及其实现
- Spring Data自定义接口实现
- Spring Data自定义Repository接口方法定义规范
- Spring技术内幕之Spring Data JPA-自定义Repository实现
- spring data 接口之 Repository
- Spring data 自定义Repository 实现Mongodb的Group by
- spring-data-mongo 实现aggregation
- spring data jpa 自定义接口实现
- spring data jpa 自定义接口实现
- spring data 自定义接口
- 利用AOP为Spring Data Jpa的接口Repository添加全局自定义过滤
- SpringBoot第四讲扩展和封装Spring Data JPA(一)_自定义Repository和创建自己的BaseRepository
- SpringBoot第四讲扩展和封装Spring Data JPA(一)_自定义Repository和创建自己的BaseRepository
- Spring Data中手动实现Repository方法
- Spring-Data-Redis-Repository中以自定义class作为id的实现
- spring data jpa 自定义接口
- VS2015 无法解析的外部符号 __vsnwprintf_s
- 网络_HttpURLConnection_原始类
- [C语言][LeetCode][141]Linked List Cycle
- java中文乱码解决之道(四)-----java编码转换过程
- Java基础--并发编程基础(1)
- [SpringBoot实践]spring-data-mongo自定义Repository接口及其实现
- android 开发 时间的计算问题
- 25
- linux下的redis+spring集群整合(七)
- lightoj 1025 - The Specials Menu 【区间dp】
- Linux进程调度——schedule()函数分析
- java中文乱码解决之道(五)-----java是如何编码解码的
- poj题目分类
- P网 虚拟币评分