jpa中查询大量数据

数据库查询一直是提升程序速度的瓶颈之一,本人也遇到了由于数据库数据查询太久致使影响失败,在这里记录如下解决的方法。数据库

描述

该功能为统计功能,根据参数查找出符合的器具信息,而后再根据统计信息得出统计数据。就比如要统计某个年级学生的优秀,良好,及格率。看起来简单容易实现,可是到了测试环境中,却出现了错误:查询太久得不到响应。测试

排查

通过打断点查看,发现系统问题出在了查询数据的过程当中。通过排查是数据过大,而且要链接的表过多,致使查询时间花费过大,前台得不到响应。hibernate

hibernate在查询时,总会自动把全部关联的数据查询出来,而关联的数据又有关联的实体,这样同样致使要链接查询的表过多。就比如学生,教师,学院这三个实体:code

class Student {
        ......
        @ManyToOne
        Teacher teacher; // 所属教师
        
        @OneToOne
        Score score; // 所属成绩
}

class Teacher {
        ......
        @ManToOne
        College college; // 所属学院
}

class College {
        .......
}

当统计学生成绩时,咱们并不须要教师的信息,可是hibernate 在查询时会自动来链接teacher表把教师的信息也查询出来,同时查询教师时还会链接学院表,把学院的数据也查询出来。这就致使了咱们须要为冗余的数据牺牲查询速度。因此解决的思路就是,在统计查询时,仅仅查询咱们须要的数据,不查询咱们不须要的数据。get

解决

在复杂的查询中,每每须要许多关联的数据,能够经过自定义查询和投影的方式,实如今hibernate中,仅仅查询本身想要的关联数据,提升查询速度。
在上面的例子中,咱们能够自定义查询:it

select name, score.score from student jion score  on score.id=student.id where grade=2019

仅仅查询学生中的名字,学生成绩中的成绩两个信息,以后再经过投影,投影到实体上:io

public interface StudengtScoreProjections {
    String name;
    Double score;
}

整合自定义查询和投影到仓库类中:class

public interface StudentRepository extends CrudRepository<Student, Long> {  
  
    @Query(value = "select name, score.score as score from student jion score s on score.id=student.id where grade=?1) ",nativeQuery = true)  
    List<StudengtScoreProjections> getAllByGrade(Long grade);  
}

为了复用查询,能够创建响应的视图,查询时从视图中查询:List

// 数据库创建视图
create view student_score as
select name, score.score as score,grade from student jion score s on score.id=student.id

// 仓库类中改成从视图中查询
public interface StudentRepository extends CrudRepository<Student, Long> {  
  
    @Query(value = "select * from student_score where grade=?1) ",nativeQuery = true)  
    List<StudengtScoreProjections> getAllByGrade(Long grade);  
}

再创建投影和实体之间的转换方法,达到查询的目的。select

总结

经过自定义查询和投影的方法,来解决hibernate自动查询关联数据的问题,使用自定义的查询,能够提升数据库查询的灵活性和速度。

相关文章
相关标签/搜索