美文网首页
JPA 基础(2)—— 分页操作

JPA 基础(2)—— 分页操作

作者: 黄宝玲_1003 | 来源:发表于2019-03-28 16:38 被阅读0次

    JPA 基础(1)—— 数据库持久化代码实战
    JPA 基础(2)—— 分页操作
    JPA 基础(3)—— Auditing
    JPA 基础(4)—— 关联表映射

    仓库PagingAndSortingRepository包装了分页和排序。

    简单分页查询

    直接根据班级号进行分页查询。

    Page<StudentEntity> findAllByClassNo(String classNo, Pageable pageable);

    自定义规范

    Page<StudentEntity> findAll(Specification<StudentEntity> spec, Pageable pageable);

    查询语句@Query

    当进行一些复杂查询时,可以用@Query显示地声明查询语句。

    @Query("select s from StudentEntity s where s.grade >= ?1 and s.classNo <> ?2 and s.no like ?3") List<StudentEntity> findAllByGrade(Integer grade, String classNo, String no);

    @Query语句还有另一种写法

    @Query(value = "select s from student s where s.grade >= ?1 and s.class_no <> ?2 and s.no like ?3", nativeQuery = true)

    因为指定了nativeQuery = true,即使用原生的sql语句查询。使用java对象'Book'作为表名来查自然是不对的。只需将Book替换为表名book。

    更新/删除

    当声明更新和删除接口时,需要增加2个注解@Transactional,因为默认事务是只读的,所以update或delete操作需要覆盖事务配置。

    @Transactional void deleteAllByClassNo(String classNo);

    代码实战

    学生实体

    @Data                     
    @Entity                   
    @Table(name = "student")  
    public class StudentEntity {
        @Id  
        private String no;
    
        @Column(name = "class_no")  
        private String classNo;
    
        private Integer grade;
    }
    

    仓库方法

    package com.jpa.test;
    
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.jpa.domain.Specification;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Query;
    
    import java.util.List;
    
    public interface StudentRepository extends JpaRepository<StudentEntity, String> {
        StudentEntity findByNo(String no);
    
        Page<StudentEntity> findAllByClassNo(String classNo, Pageable pageable);
    
    //    @Modifying  // JPQL并不支持INSERT语句,但可以使用UPDATE和DELETE语句,要想使用UPDATE或DELETE语句则需要在@Query注解上@Modifying注解,以通知该JPQL为更新或删除操作。
    //    @Query(value = "select s from student s where s.grade >= ?1 and s.class_no <> ?2 and s.no like ?3", nativeQuery = true)
        @Query(value = "select s from StudentEntity s where s.grade >= ?1 and s.classNo <> ?2 and s.no like ?3")
        List<StudentEntity> getGoodStudent(Integer grade, String classNo, String no);
    
        Page<StudentEntity> findAll(Specification<StudentEntity> spec, Pageable pageable);
    
        @Transactional  // 默认事务是只读的,所以update或delete需要覆盖事务配置
        void deleteAllByClassNo(String classNo);
    }
    

    测试

    package com.jpa.test;
    
    import org.junit.jupiter.api.Test;
    import org.junit.jupiter.api.extension.ExtendWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.jpa.domain.Specification;
    import org.springframework.lang.Nullable;
    import org.springframework.test.context.junit.jupiter.SpringExtension;
    
    import javax.persistence.criteria.CriteriaBuilder;
    import javax.persistence.criteria.CriteriaQuery;
    import javax.persistence.criteria.Predicate;
    import javax.persistence.criteria.Root;
    import java.util.ArrayList;
    import java.util.List;
    
    @ExtendWith(value = {SpringExtension.class})
    @SpringBootTest
    public class StudentService {
        @Autowired
        private StudentRepository studentRepository;
    
        @Test
        public void getInfo() {
            // 构建一个学生实体
            StudentEntity studentEntity = new StudentEntity();
            for (int i = 1; i < 10; i++) {
                studentEntity.setNo("20140801032" + String.valueOf(i));
                studentEntity.setClassNo("317");
                studentEntity.setGrade(60+i);
                // 插入数据
                studentRepository.save(studentEntity);
            }
    
            System.out.println(studentRepository.findByNo("201408010320"));
        }
    
        @Test
        public void getPageClassNo() {
            Page<StudentEntity> page = studentRepository.findAllByClassNo("317", PageRequest.of(0, 3));
            page.getContent().forEach(System.out::println);
        }
    
        @Test
        public void getPageClassNoSort() {
            Sort sort = Sort.by("grade").descending();  // 以成绩降序排列
            Page<StudentEntity> page = studentRepository.findAllByClassNo("317", PageRequest.of(0, 3, sort));
            page.getContent().forEach(System.out::println);
        }
    
        @Test
        public void getGoodStudent() {
            List<StudentEntity> list = studentRepository.getGoodStudent(80, "317", "2014%");  // 注意通配符'%'不要漏写
            list.forEach(System.out::println);
        }
    
        @Test
        public void getAllSpecificationStudent() {
            // 构造specification
            // 多说一句:<?> 是范型通配符
            Specification<StudentEntity> spec = (Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) -> {
                // 谓词
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(criteriaBuilder.greaterThan(root.get("grade"), 60));
                criteriaQuery.orderBy(criteriaBuilder.desc((root.get("grade"))));
                criteriaQuery.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
    
                return criteriaQuery.getRestriction();
            };
            Page<StudentEntity> page = studentRepository.findAll(spec, PageRequest.of(0, 3));
            page.getContent().forEach(System.out::println);
        }
    }
    

    结果

    表记录 获取第一页信息,每页3条记录 分页排序,按成绩由高到低排 查询2014级非317班的成绩80分以上的同学 复杂谓词查询

    相关文章

      网友评论

          本文标题:JPA 基础(2)—— 分页操作

          本文链接:https://www.haomeiwen.com/subject/chwgvqtx.html