mongorepository查询条件_MongoDB动态条件之分页查询
一、使用QueryByExampleExecutor
遵循MongoRepository; public interface StudentRepository extends MongoRepository {
}
代码实现采用ExampleMatcher这一匹配器;仅限于对字符串进行模糊检索;而对其他数据类型则实施精确匹配
Example封装实体类和匹配器
使用QueryByExampleExecutor接口中的findAll方法
public Page getListWithExample(StudentReqVO studentReqVO) {
Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
创建一个实例 pageable = PageRequest.创建方法(学生请求体中的页码, 学生请求体中的页大小, 排序方式);
Student student = new Student();
BeanUtils.copyProperties(studentReqVO, student);
//创建匹配器,即如何使用查询条件
ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
.withStringMatcher(ExampleMatcher.StringMatcher.COUNTAINS) //修改默认的字符串匹配策略为模糊搜索
.withIgnoreCase(true) //改变默认大小写忽略方式:忽略大小写
.query("名称", ExampleMatcher.GenericPropertyMatchers.contains())
.withIgnorePaths("pageNum", "pageSize"); //忽略属性,不参与查询
//创建实例
Example example = Example.of(student, matcher);
Page students = studentRepository.findAll(example, pageable);
return students;
}
局限性:该系统无法使用OR运算符进行过滤条件设置。具体来说,所有的过滤逻辑均采用AND运算进行组合
不支持两个值的范围查询,如时间范围的查询
二、MongoTemplate结合Query
实现一:使用Criteria封装查询条件
public Page getListWithCriteria(StudentReqVO studentReqVO) {Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
Pagable$pageable = PageRequest.Of(studentReqVO, sort);
Query query = new Query();
//动态拼接查询条件
if (!StringUtils.isEmpty(studentReqVO.getName())){
创建一个Pattern类型的变量pattern,并使用Pattern.compile方法来编译包含student request value object(SRVO)名称的正则表达式模式匹配操作。该操作采用CASE_INSENSITIVE flags参数以忽略大小写差异。
query.addCriteria(Criteria.where("name").regex(pattern));
}
if (studentReqVO.getSex() != null){
query.addCriteria(Criteria.where("sex").is(studentReqVO.getSex()));
}
if (studentReqVO.getCreateTime() != null){
在查询中添加一个筛选标准为'时间字段小于等于学生需求版本的时间戳'的条件
}
//计算总数
long total = mongoTemplate.count(query, Student.class);
//查询结果集
ArrayList studentList = mongoTemplate.MongoDB集合操作方法.find(带分页功能的查询, Student.class);
Page studentPage = new PageImpl(studentList, pageable, total);
return studentPage;
}
实现二:使用Example和Criteria封装查询条件
public Page getListWithExampleAndCriteria(实例 studentReqVO) {根据创建时间降序排列;}
PageableType pageable = PageRequest.create(studentReqVO的学生数量, studentReqVO的学生每页人数, sort);
Student student = new Student();
BeanUtils.copyProperties(studentReqVO, student);
//创建匹配器,即如何使用查询条件
ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //修改字符串匹配逻辑:通配符搜索
.withIgnoreCase(true) //改变默认大小写忽略方式:忽略大小写
.withMatcher("name", ExampleMatcher GenericPropertyMatchers contains()) // 采用"包含匹配"的方式查询标题
.withIgnorePaths("pageNum", "pageSize"); //忽略属性,不参与查询
//创建实例
Example example = Example.of(student, matcher);
Query query = new Query(Criteria.byExample(example));
if (studentReqVO.getCreateTime() != null){
query.addCriteria(Criteria.where("createTime").lte(studentReqVO.getCreateTime()));
}
//计算总数
long total = mongoTemplate.count(query, Student.class);
//查询结果集
studentList = mongoTemplate.find(query.with(pageable), Student.class);
Page studentPage = new PageImpl(studentList, pageable, total);
return studentPage;
}
缺点:不支持返回固定字段
三、MongoTemplate结合BasicQueryBasicQuery是Query的子类
支持返回固定字段
public Page getListWithBasicQuery(StudentReqVO studentReqVO) {
Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
Create a Pageable object named pageable and retrieve the page details by calling PageRequest.of with the number of pages, page size, and sort parameter.
QueryBuilder queryBuilder = new QueryBuilder();
//动态拼接查询条件
if (!StringUtils.isEmpty(studentReqVO.getName())) {
按照如下方式编译正则表达式模式:
Pattern pattern = Pattern.compile("^." + studentReqVO.getName() + ".$", ignoreCase);
queryBuilder.and("name").regex(pattern);
}
if (studentReqVO.getSex() != null) {
queryBuilder.and("sex").is(studentReqVO.getSex());
}
if (studentReqVO.getCreateTime() != null) {
queryBuilder.withAnd(studentReqVO).isLessOrEqualTo("createTime").isLessOrEqualTo(getCreateTime());
}
Query query = new BasicQuery(queryBuilder.get().toString());
//计算总数
long total = mongoTemplate.count(query, Student.class);
//查询结果集条件
BasicDBObject fieldsObject = new BasicDBObject();
//id默认有值,可不指定
fieldsObject.append("id", 1) //1查询,返回数据中有值;0不查询,无值
.append("name", 1);
query = new BasicQuery(queryBuilder.get().toString(), fieldsObject.toJson());
//查询结果集
该代码行用于从MongoDB数据库中获取满足特定条件的学生数据,并将结果转换为一个Student对象的列表。
Page studentPage = new PageImpl(studentList, pageable, total);
return studentPage;
}
四、MongoTemplate结合Aggregation使用Aggregation聚合查询
支持返回固定字段
支持分组计算总数、求和、平均值、最大值、最小值等等
public Page getListWithAggregation(StudentReqVO studentReqVO) {
Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
Pageable instance pageable = PageRequest.of(studentReqVO.getPageNumber(), studentReqVO.getPageSize(), sort);
Integer pageNum = studentReqVO.getPageNum();
Integer pageSize = studentReqVO.getPageSize();
List operations = new ArrayList<>();
if (!StringUtils.isEmpty(studentReqVO.getName())) {
Pattern pattern = Pattern.compile("从字符串开始到任意字符(包括空字符)" + studentReqVO.getName() + "到字符串结束", Pattern.CASE_INSENSITIVE);
Criteria criteria = Criteria.where("name").regex(pattern);
operations.add(Aggregation.match(criteria));
}
if (null != studentReqVO.getSex()) {
operations.insert(Aggregation.match(where(sex).is(studentReqVO.getSex())));
}
long totalCount = 0;
//获取满足添加的总页数
if (null != operations && operations.size() > 0) {
集合 aggregationCount 被初始化为新集合实例(operations);// 当 operations 为空时会导致错误
int aggregationResultCount = mongoTemplate.aggregate(aggregationResultCount, "student", Students.class);
totalCount = resultsCount.getMappedResults().size();
} else {
List list = mongoTemplate.findAll(Student.class);
totalCount = list.size();
}
operations.add(Aggregation.skip((long) pageNum * pageSize));
operations.add(Aggregation.limit(pageSize));
operations.add(Aggregation.sort(Sort.Direction.DESC, "createTime"));
Aggregation aggregation = Aggregation.newAggregation(operations);
AggregationResults results = mongoDBTemplate.executeAggregation(aggregation, "student", "Student表");
//查询结果集
创建一个实例studentPage,并将其赋值为由PageImpl类构造函数调用results.getMappedResults()和poundable参数生成的对象,并包含totalCount的值。
return studentPage;
}
