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自動查詢關聯數據的問題,使用自定義的查詢,能夠提升數據庫查詢的靈活性和速度。

相關文章
相關標籤/搜索