[SpringBoot实践]spring-data-mongo自定义Repository接口及其实现
2016-04-14 21:45
746 查看
概述
通常我们使用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
@Document public 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. */ @NoRepositoryBean trait 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。
相关文章推荐
- 分享微信开发Html5轻游戏中的几个坑
- 如何在 Fedora 上安装 MongoDB 服务器
- PHP添加yaf xhprof mongodb 同理
- mongodb安装
- 如何在 Ubuntu 上安装 MongoDB
- 信息安全聚合 Sec-News 的重构之路
- perl操作MongoDB报错undefined symbol: HeUTF8解决方法
- C#中使用1.7版本驱动操作MongoDB简单例子
- 使用zabbix监控mongodb的方法
- Node.js的MongoDB驱动Mongoose基本使用教程
- MongoDB系列教程(四):设置用户访问权限
- php实现的mongodb操作类实例
- 解决mongodb在ubuntu下启动失败,提示couldn‘t remove fs lock errno:9 Bad file descriptor的错误
- 在PostgreSQL的基础上创建一个MongoDB的副本的教程
- 关于mongoose连接mongodb重复访问报错的解决办法
- java操作mongodb示例分享
- php对mongodb的扩展(初出茅庐)
- 作为PHP程序员应该了解MongoDB的五件事
- 基于MySQL到MongoDB简易对照表的详解
- MongoDB入门教程之C#驱动操作实例