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

2019-03-28  本文已影响0人  黄宝玲_1003

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分以上的同学 复杂谓词查询
上一篇下一篇

猜你喜欢

热点阅读