个人博客
1、Specifications进行查询
在一些查询条件不固定的场景下,我们需要动态去组装查询条件。在Spring Data JPA中可以通过 JpaSpecificationExecutor
接口查询。相比JPQL,其优势是类型安全,更加的面向对象。
1.1、创建Repository
需要继承 JpaSpecificationExecutor
接口。
1 2 3
| public interface SpecificationRepository extends JpaRepository<Actor, Long>, JpaSpecificationExecutor<Actor> {
}
|
1.2、Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @Service @Transactional @Slf4j public class SpecificationServiceImpl implements SpecificationService { @Autowired private SpecificationRepository specificationRepository;
@Override public List<Actor> findBySpecification(Long id, Integer age, Integer page, Integer pageSize) { Specification<Actor> specification = (Specification<Actor>) (root, criteriaQuery, criteriaBuilder) -> { List<Predicate> list = new ArrayList<>();
list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("id"), (id == null || id < 0) ? 0 : id)); if(age != null && age > 0) { list.add(criteriaBuilder.equal(root.get("actorAge"), age)); }
Predicate[] predicates = new Predicate[list.size()]; list.toArray(predicates); return criteriaBuilder.and(predicates); };
Sort sort = new Sort(Sort.Direction.ASC, "id"); PageRequest pageRequest = PageRequest.of(page < 0 ? 0 : page, pageSize, sort); Page<Actor> actorPage = specificationRepository.findAll(specification, pageRequest); log.info("分页查询第:[{}]页,pageSize:[{}],共有:[{}]数据,共有:[{}]页", page, pageSize, actorPage.getTotalElements(), actorPage.getTotalPages()); List<Actor> actorListBySpecification = actorPage.getContent(); return actorListBySpecification; } }
|
判断条件值是否存在,动态追加条件。
注意指定的字段是实体类中的属性名而非表中的字段名。
1.3、测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class SpecificationTest { @Autowired private SpecificationService specificationService;
@Test public void testSpecification() { List<Actor> actorList = specificationService.findBySpecification(1L, null, 0, 10); log.info(JSONUtil.toJsonPrettyStr(actorList)); } }
|
多次修改查询条件测试,可以看出查询条件是根据实际情况动态追加的。
2、ExampleMatcher进行查询
2.1、创建Repository
1 2 3
| public interface ExampleMatcherRepository extends JpaRepository<Actor, Long> { }
|
2.2、Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| @Service @Transactional @Slf4j public class ExampleMatcherServiceImpl implements ExampleMatcherService { @Autowired private ExampleMatcherRepository exampleMatcherRepository;
@Override public List<Actor> findByExampleMatcher(String actorEmailPre, String actorNamePre, Integer page, Integer pageSize) { Actor actor = new Actor(); actor.setActorEmail(actorEmailPre); actor.setActorName(actorNamePre); ExampleMatcher matcher = ExampleMatcher.matching() .withMatcher("actorEmail", ExampleMatcher.GenericPropertyMatchers.startsWith()) .withMatcher("actorName", ExampleMatcher.GenericPropertyMatchers.startsWith()) .withIgnoreCase() .withIgnoreNullValues() .withIgnorePaths("actorAge", "createTime");
Example<Actor> actorExample = Example.of(actor, matcher);
Sort sort = new Sort(Sort.Direction.ASC, "actorAge"); PageRequest pageRequest = PageRequest.of(page < 0 ? 0 : page, pageSize, sort); Page<Actor> actorPage = exampleMatcherRepository.findAll(actorExample, pageRequest); log.info("分页查询第:[{}]页,pageSize:[{}],共有:[{}]数据,共有:[{}]页", page, pageSize, actorPage.getTotalElements(), actorPage.getTotalPages()); List<Actor> actorListByExampleMatcher = actorPage.getContent(); return actorListByExampleMatcher; } }
|
模糊查询匹配字符串。
2.3、测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RunWith(SpringRunner.class) @SpringBootTest @Slf4j public class ExampleMatcherTest { @Autowired private ExampleMatcherService exampleMatcherService;
@Test public void testExampleMatcher() { List<Actor> actorList = exampleMatcherService.findByExampleMatcher("EMAIL", "name", 0, 10); log.info(JSONUtil.toJsonPrettyStr(actorList)); } }
|
代码地址