SpringDataJPA(四)多条件查询接口JpaSpecificationExecutor的使用

浅浅的花香味﹌ 2021-12-17 02:37 821阅读 0赞

源码

GitHub: https://github.com/291685399/springboot-learning/tree/master/springboot-springdatajpa04

JpaSpecificationExecutor接口

  • JpaSpecificationExecutor接口是单独存在的,完全独立的
  • 该接口主要是提供了多条件查询的支持,并且可以在查询中添加分页与排序
  • 该接口需要配合其他接口(例如Repository、CurdRepository、JPARepository、PagingAndSortingRepositor)进行使用,要不然注入实现接口对象的时候会报错,在IOC容器中不能找到该bean

JpaSpecificationExecutor接口中声明了五个方法,下面将介绍这五个方法的使用

  1. public interface JpaSpecificationExecutor<T> {
  2. Optional<T> findOne(@Nullable Specification<T> var1);
  3. List<T> findAll(@Nullable Specification<T> var1);
  4. Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
  5. List<T> findAll(@Nullable Specification<T> var1, Sort var2);
  6. long count(@Nullable Specification<T> var1);
  7. }

使用JpaSpecificationExecutor接口

pom.xml:

  1. <dependencies>
  2. <!-- springboot -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-test</artifactId>
  10. <scope>test</scope>
  11. </dependency>
  12. <!-- springdatajpa -->
  13. **<dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-data-jpa</artifactId>
  16. </dependency>**
  17. <!-- mysql -->
  18. <dependency>
  19. <groupId>mysql</groupId>
  20. <artifactId>mysql-connector-java</artifactId>
  21. <scope>runtime</scope>
  22. </dependency>
  23. <!-- lombok -->
  24. <dependency>
  25. <groupId>org.projectlombok</groupId>
  26. <artifactId>lombok</artifactId>
  27. <optional>true</optional>
  28. </dependency>
  29. </dependencies>

application.properties:

  1. # datasource
  2. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot-springdatajpa04?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
  3. spring.datasource.driver-class-name=com.mysql.jdbc.Driver
  4. spring.datasource.username=root
  5. spring.datasource.password=root
  6. # springdatajpa
  7. #打印出自动生产的SQL,方便调试的时候查看
  8. spring.jpa.show-sql=true
  9. #更新数据库表结构
  10. spring.jpa.hibernate.ddl-auto=update
  11. #对打印的sql进行格式化,方便查看
  12. spring.jpa.properties.hibernate.format_sql=true
  13. spring.jpa.properties.hibernate.use_sql_comments=true
  14. #指定生成表名的存储引擎为InneoDB
  15. spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

User:

  1. @Entity
  2. @Data
  3. @Table(name = "user")
  4. public class User implements Serializable {
  5. @Id
  6. @GeneratedValue(strategy = GenerationType.AUTO)
  7. @Column(name = "id")
  8. private int id;
  9. private String name;
  10. private Integer age;
  11. private String sex;
  12. private String address;
  13. private String phone;
  14. }

UserJPASpecificationExecutor:

  1. public interface UserJPASpecificationExecutor extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
  2. }

UserRepositoryTests:

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class UserJPASpecificationExecutorTests {
  4. @Autowired
  5. private UserJPASpecificationExecutor userJPASpecificationExecutor;
  6. /** * findOne */
  7. @Test
  8. public void findAllTest1() {
  9. Specification<User> specification = new Specification<User>() {
  10. @Override
  11. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  12. //select * from user where phone='12345697842'
  13. return criteriaBuilder.equal(root.get("phone"), "12345697842");
  14. }
  15. };
  16. Optional<User> userOptional = userJPASpecificationExecutor.findOne(specification);
  17. User user = userOptional.get();
  18. System.out.println(user);
  19. }
  20. /** * List<T> findAll(@Nullable Specification<T> var1); */
  21. @Test
  22. public void findAllTest2_1() {
  23. /** * Specification<User>:用于封装查询条件 */
  24. Specification<User> specification = new Specification<User>() {
  25. /** * Predicate:封装单个查询条件 * @param root:查询对象的属性封装,或者说是User的包装类 * @param criteriaQuery:封装了要执行的查询中的各个部分的信息,select、from、order by * @param criteriaBuilder:查询条件的构造器,定义不同的查询条件 * @return */
  26. @Override
  27. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  28. //select * from user where name='张三'
  29. Predicate predicate = criteriaBuilder.equal(root.get("name"), "张三");
  30. return predicate;
  31. }
  32. };
  33. List<User> userList = userJPASpecificationExecutor.findAll(specification);
  34. System.out.println(userList);
  35. }
  36. /** * List<T> findAll(@Nullable Specification<T> var1); */
  37. @Test
  38. public void findAllTest2_2() {
  39. Specification<User> specification = new Specification<User>() {
  40. @Override
  41. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  42. //select * from user where name='张三' and age ='34'
  43. List<Predicate> predicateList = new ArrayList<>();
  44. predicateList.add(criteriaBuilder.equal(root.get("name"), "张三"));
  45. predicateList.add(criteriaBuilder.equal(root.get("age"), 34));
  46. Predicate[] predicates = new Predicate[predicateList.size()];
  47. return criteriaBuilder.and(predicateList.toArray(predicates));
  48. //或者使用:return criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "张三"),criteriaBuilder.equal(root.get("age"), 34));
  49. }
  50. };
  51. List<User> userList = userJPASpecificationExecutor.findAll(specification);
  52. System.out.println(userList);
  53. }
  54. /** * Page<T> findAll(@Nullable Specification<T> var1, Pageable var2); */
  55. @Test
  56. public void findAllTest3() {
  57. Specification<User> specification = new Specification<User>() {
  58. @Override
  59. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  60. //select * from user where name='张三' and age ='34'
  61. return criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "张三"), criteriaBuilder.equal(root.get("age"), 34));
  62. }
  63. };
  64. //order by id desc limit 0,1
  65. PageRequest pageRequest=new PageRequest(0,1,new Sort(Sort.Direction.DESC,"id"));
  66. Page<User> userPage = userJPASpecificationExecutor.findAll(specification, pageRequest);
  67. List<User> userList = userPage.getContent();
  68. System.out.println(userList);
  69. }
  70. /** * List<T> findAll(@Nullable Specification<T> var1, Sort var2); */
  71. @Test
  72. public void findAllTest4() {
  73. Specification<User> specification = new Specification<User>() {
  74. @Override
  75. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  76. //select * from user where name='张三' and age ='34'
  77. return criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "张三"), criteriaBuilder.equal(root.get("age"), 34));
  78. }
  79. };
  80. //order by id desc
  81. Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "id"));
  82. List<User> userList = userJPASpecificationExecutor.findAll(specification, sort);
  83. System.out.println(userList);
  84. }
  85. /** * long count(@Nullable Specification<T> var1); */
  86. @Test
  87. public void findAllTest5() {
  88. Specification<User> specification = new Specification<User>() {
  89. @Override
  90. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  91. //select * from user where name='张三'
  92. return criteriaBuilder.equal(root.get("name"), "张三");
  93. }
  94. };
  95. long count = userJPASpecificationExecutor.count(specification);
  96. System.out.println(count);
  97. }
  98. }

发表评论

表情:
评论列表 (有 0 条评论,821人围观)

还没有评论,来说两句吧...

相关阅读