數據庫查詢一直是提升程序速度的瓶頸之一,本人也遇到了由於數據庫數據查詢太久致使影響失敗,在這裏記錄如下解決的方法。數據庫
該功能爲統計功能,根據參數查找出符合的器具信息,而後再根據統計信息得出統計數據。就比如要統計某個年級學生的優秀,良好,及格率。看起來簡單容易實現,可是到了測試環境中,卻出現了錯誤:查詢太久得不到響應。測試
通過打斷點查看,發現系統問題出在了查詢數據的過程當中。通過排查是數據過大,而且要鏈接的表過多,致使查詢時間花費過大,前臺得不到響應。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
自動查詢關聯數據的問題,使用自定義的查詢,能夠提升數據庫查詢的靈活性和速度。