Advertisement

Spring data jpa 查询条件+分页查询

阅读量:

1,依赖

2,application.yml

复制代码
 server:

    
   port: 8082
    
  
    
 #数据库连接
    
 spring:
    
   datasource:
    
     driver-class-name: com.mysql.jdbc.Driver
    
     url: jdbc:mysql://localhost:3306/my_test?useUnicode=true&characterEncoding=utf-8
    
     username: root
    
     password: root
    
     
    
 #spring-data-jpa,根据实体类生成表
    
   jpa:
    
     hibernate: 
    
       ddl-auto: update
    
     show-sql: true

3,实体类,jpa使用实体类生成数据库

复制代码
 @Data

    
 @NoArgsConstructor
    
 @AllArgsConstructor
    
 @Entity
    
 @Table(name="student")
    
 public class Student {
    
     @Id
    
     @GeneratedValue
    
     private Integer id;
    
     private String code;
    
     private String name;
    
     private Integer sex;
    
     private Integer age;
    
     @Temporal(TemporalType.DATE)//获取的时候得到yyyy-MM-dd格式日期
    
     private Date birthDate;
    
 }

4, dao

复制代码
 //JpaSpecificationExecutor:自定义条件分页查询

    
 public interface StudentRepository extends JpaRepository<Student,Integer>, JpaSpecificationExecutor<Student> {
    
 //        方式1:方法名称规则查询
    
     Student findByName(String name);
    
  
    
     @Query(value = "select * from student where id=?1",nativeQuery=true)
    
     Student findStudentById(int id);
    
  
    
 //    方式1:方法名称规则查询
    
 //    List<Student> findByNameAndCodeLike(String name, String code);
    
  
    
 //    方式2:@Query
    
 //如果当前执行的是一个更新操作时候,还要加上@Modifying注解
    
 //赋值时,默认的情况下,占位符的位置和方法参数位置一致。如果不一致,
    
 //可以使用?+数字 索引的方式,指定占位的取值位置。
    
     @Query(value="select * from student where code like ?2 and name like ?1",nativeQuery=true)
    
     List<Student> findByNameAndCodeLike(String name, String code);
    
  
    
 }

5,service

复制代码
 public interface StudentService {

    
     Student saveStu(Student s);
    
     void delStu(Integer id);
    
     Student updateStu(Student s);
    
     Student findStuById(Integer id);
    
     Student findByName(String name);
    
     List<Student> findByNameAndCodeLike(String name ,String code);//模糊查询
    
     Page<Student> findAll(Pageable var2);//分页查询
    
     Page<Student> findAll(Pageable var2,Student s);//分页+条件查询
    
 }

6,serviceImpl

复制代码
     /** * 不带条件的简单分页
    
      * @param p
    
      * @return
    
      */
    
     @Override
    
     public Page<Student> findAll(Pageable p) {
    
     Page<Student> all = studentRepository.findAll(p);
    
     return all;
    
     }
复制代码
     /** * 方式1
    
      * 动态条件查询+分页
    
      * * @param pageable
    
      * @param s
    
      * @return
    
      */
    
     @Override
    
     public Page<Student> findAll(Pageable pageable, Student s) {
    
     Page<Student> all = studentRepository.findAll(new Specification<Student>() {
    
         @Override
    
         public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
    
 //                Pridicate:表示一个查询条件
    
             List<Predicate> predicates = new ArrayList<Predicate>();//创建一个条件集合
    
 //                获取属性
    
             Path<String> name = root.get("name");
    
             Path<String> code = root.get("code");
    
 //                构造查询条件
    
             Predicate p1 = cb.like(name, "%" + s.getName() + "%");
    
             Predicate p2 = cb.like(code, "%" + s.getCode() + "%");
    
             predicates.add(p1);
    
             predicates.add(p2);
    
 //                predicates.add(cb.like(root.get("name"),"%"+s.getName()+"%"));
    
 //                predicates.add(cb.like(root.get("code"),"%"+s.getCode()+"%"));
    
  
    
             //必须使用toArray(T[])的有参数方法,因为cq.where(p)中的参数的类型必须是Predicate[]数组类型。
    
             //toArray()无参返回的是一个Object类型。
    
             //新建数组方式之一:new A[number]
    
             Predicate[] p = predicates.toArray(new Predicate[predicates.size()]);
    
             cq.where(p);
    
  
    
             return null;
    
         }
    
     }, pageable);
    
     return all;
    
     }
    
  
    
  
    
     /** * 方式2
    
      * @param pageable
    
      * @param s
    
      * @return
    
      */
    
 //    @Override
    
 //    public Page<Student> findAll(Pageable pageable, Student s) {
    
 //        Page<Student> all = studentRepository.findAll(new Specification<Student>() {
    
 //            @Override
    
 //            public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
    
 //                Predicate p1 = cb.like(root.get("name"), s.getName());
    
 //                Predicate p2 = cb.like(root.get("code"), s.getCode());
    
 //                Predicate and = cb.and(p1, p2);
    
 //                return and;
    
 //            }
    
 //        }, pageable);
    
 //        return all;
    
 //    }

7,controller

复制代码
     @ResponseBody

    
     @GetMapping("findAll")
    
     Page<Student> findAll(@PageableDefault(size = 3) Pageable var2){
    
     Page<Student> all = studentService.findAll(var2);
    
     return all;
    
     }//分页查询
    
  
    
     @ResponseBody
    
     @GetMapping("findAllBys")
    
     Page<Student> findAllBys(@PageableDefault(size = 3) Pageable var2,Student s){
    
     s.setName("a");
    
     s.setCode("a");
    
     Page<Student> all = studentService.findAll(var2, s);
    
     return all;
    
     }//分页+条件查询

数据库结果和数据:

条件+分页查询结果:

8,总结:

jpa动态查询主要使用JpaSpecificationExecutor接口里面的方法和Specification接口。

JpaSpecificationExecutor接口方法:

复制代码
 public interface JpaSpecificationExecutor<T> {

    
     T findOne(Specification<T> var1);  //查询单个对象:
    
  
    
     List<T> findAll(Specification<T> var1); //查询列表
    
  
    
     Page<T> findAll(Specification<T> var1, Pageable var2); //分页查询,Specification:查询条件、Pageable:分页条件
    
  
    
     List<T> findAll(Specification<T> var1, Sort var2);//排序
    
  
    
     long count(Specification<T> var1);//统计查询
    
 }

Specification接口方法:

复制代码
 public interface Specification<T> {

    
     Predicate toPredicate(Root<T> var1, CriteriaQuery<?> var2, CriteriaBuilder var3);//封装查询条件的方法
    
 }

参数说明:

Specification:表示查询条件,把所有的条件封装到这个对象中,传递到实现JpaSpecificationExecutor对象的方法
做法:自定义我们自己的Specification实现类,实现Specification
Root:查询的根对象(查询的任何属性都可以从根对象中获取),主要获取查询对象属性。
CriteriaQuery:(顶层查询对象,自定义查询方式(不常用)
CriteriaBuilder:查询的构造器,封装了很多的查询条件,如(模糊匹配
equal:直接获取Path对象的属性,然后进行比较即可,但是如:
gt,lt,ge,like等:需要得到path,并指定比较的参数类型:path.as(类型的字节码对象)

@PageableDefault注解,可以看到都有默认值,当然也可覆盖其参数值

方法名称规则查询:

1,findBy+属性名称 :根据属性名称进行查询。
2,fingBy+属性名称+查询方式(Like 或 null 等) :根据属性名称+查询方式进行查询。
3,findBy+属性名称+查询方式+多条件连接符(and 或or 等) +属性名+ 查询方式

如:List findByEmailAddressAndLastname(String emailAddress, String lastname);

更多查看:https://docs.spring.io/spring-data/jpa/docs/2.3.0.RELEASE/reference/html/#jpa.query-methods.named-queries

分页方式2:利用 PageRequest.of()方法。

复制代码
 @GetMapping("stu/list/{page}/{size}")

    
 public R listStudentPage(@PathVariable("page") int page ,@PathVariable("page") int size ){
    
 	if(page<1){
    
 	page=1;
    
 	}
    
 	if(size<=0){
    
 	size=10
    
 	}
    
 	Sort sort = new Sort(Sort.Direction.DESC, "createTime");//排序
    
 	Pageable pageable = PageRequest.of(page-1,size,sort);
    
 	Page<Student>result = stuDao.findAll(pageable);
    
 	return R.data(result);
    
 	
    
 }

全部评论 (0)

还没有任何评论哟~