如何配置ExampleMatcher筛选dateOfDeletion为null的实体?
解决方法
下面提供几种在数据库层面完成过滤、保证分页正确性的方案,按推荐优先级排序:
1. 修改Example查询,加入dateOfDeletion=null的过滤条件
Example默认会忽略实体中值为null的字段,所以需要调整配置让dateOfDeletion IS NULL被加入查询条件:
// 构建查询实体,设置需要匹配的字段 MyEntity probe = new MyEntity(); probe.setField1(request.getField1()); probe.setField2(request.getField2()); probe.setField3(request.getField3()); // 设置dateOfDeletion为null,用于后续匹配 probe.setDateOfDeletion(null); // 自定义匹配规则 ExampleMatcher matcher = ExampleMatcher.matching() // 对field1/2/3做忽略大小写的子串匹配 .withMatcher("field1", match -> match.contains().ignoreCase()) .withMatcher("field2", match -> match.contains().ignoreCase()) .withMatcher("field3", match -> match.contains().ignoreCase()) // 关键:让实体中的null字段(即dateOfDeletion)作为查询条件,生成`IS NULL`语句 .withIncludeNullValues(); // 构建Example并执行分页查询 Example<MyEntity> example = Example.of(probe, matcher); Page<MyEntity> result = myEntityRepository.findAll(example, myPageable);
2. 使用JpaSpecificationExecutor构建动态查询
如果后续需要扩展更多复杂条件,这种方式更灵活。首先让你的Repository继承JpaSpecificationExecutor:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, JpaSpecificationExecutor<MyEntity> { }
然后构建Specification组合条件:
Specification<MyEntity> spec = (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); // 强制过滤dateOfDeletion为null的实体 predicates.add(cb.isNull(root.get("dateOfDeletion"))); // 处理field1的忽略大小写子串匹配(仅当参数非空时加入) if (StringUtils.hasText(request.getField1())) { predicates.add( cb.like( cb.lower(root.get("field1")), "%" + request.getField1().toLowerCase() + "%" ) ); } // 同理处理field2和field3 if (StringUtils.hasText(request.getField2())) { predicates.add( cb.like( cb.lower(root.get("field2")), "%" + request.getField2().toLowerCase() + "%" ) ); } if (StringUtils.hasText(request.getField3())) { predicates.add( cb.like( cb.lower(root.get("field3")), "%" + request.getField3().toLowerCase() + "%" ) ); } return cb.and(predicates.toArray(new Predicate[0])); }; // 执行分页查询 Page<MyEntity> result = myEntityRepository.findAll(spec, myPageable);
3. 自定义Repository查询方法
如果查询条件固定,直接在Repository中写JPQL查询最直观:
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> { @Query("SELECT e FROM MyEntity e WHERE e.dateOfDeletion IS NULL " + "AND (:field1 IS NULL OR LOWER(e.field1) LIKE LOWER(CONCAT('%', :field1, '%'))) " + "AND (:field2 IS NULL OR LOWER(e.field2) LIKE LOWER(CONCAT('%', :field2, '%'))) " + "AND (:field3 IS NULL OR LOWER(e.field3) LIKE LOWER(CONCAT('%', :field3, '%')))") Page<MyEntity> findActiveEntities(String field1, String field2, String field3, Pageable pageable); }
调用时直接传参即可:
Page<MyEntity> result = myEntityRepository.findActiveEntities( request.getField1(), request.getField2(), request.getField3(), myPageable );
内容的提问来源于stack exchange,提问作者osky9913
相关产品推荐
相关产品推荐

