hibernate查詢緩存(hibernate默認是關閉的)
查詢緩存是針對普通屬性結果集的緩存
對實體對象的結果集只緩存id
查詢緩存的生命周期,當前關聯的表發生修改,那么查詢緩存生命周期結束
查詢緩存的配置和使用:
1. 啟用查詢緩存:在hibernate.cfg.xml中加入:
<property name=”hibernate.cache.use_query_cache”>true</property>
2. 在程序中必須手動啟用查詢緩存,如:query.setCacheable(true);
測試查詢緩存:
一. 開啟查詢緩存,關閉二級緩存,開啟一個session,分別調用query.list (查詢屬性)
Query query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
List names = query.list();
for(Iterator iter = names.terator();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
System.out.println(“------------------------------------------”);
query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
names = query.list();
for(Iterator iter = names.terator();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
第二次沒有去查詢數據庫,因為啟用了查詢緩存
二. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list (查詢屬性)
Query query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
List names = query.list();
for(Iterator iter = names.terator();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
session.close();
System.out.println(“------------------------------------------”);
………
Query query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
List names = query.list();
for(Iterator iter = names.terator();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
第二次沒有去查詢數據庫,因為查詢緩存生命周期與session生命周期無關
三. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.iterate (查詢屬性)
Query query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
for(Iterator iter =query.iterate();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
session.close();
System.out.println(“------------------------------------------”);
………
Query query = session.createQuery(“select s.name from Student s”);
//啟用查詢緩存
query.setCacheable(true);
for(Iterator iter = query.iterate();iter.hasNext();){
String name = (String)iter.next();
System.out.println(name);
}
第二去查詢數據庫,因為查詢緩存只對query.list()起作用,對query.iterate()不起作用,也就是說query.iterate()不使用查詢緩存
四. 關閉查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)
Query query = session.createQuery(“ from Student s”);
//query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
session.close();
System.out.println(“------------------------------------------”);
………
Query query = session.createQuery(“ from Student s”);
//query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
第二去查詢數據庫,因為list默認每次都會發出查詢sql
五. 開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)
Query query = session.createQuery(“ from Student s”);
query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
session.close();
System.out.println(“------------------------------------------”);
………
Query query = session.createQuery(“ from Student s”);
query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
第二去查詢數據庫時,會發出N條sql語句,因為開啟了查詢緩存,關閉了二級緩存,那么查詢緩存會緩存實體對象的id,所以hibernate會根據實體對象的id去查詢相應的實體,如果緩存中不存在相應的實體,那么將發出根據實體id查詢的sql語句,否則不會發出sql,使用緩存中的數據
六. 開啟查詢緩存,開啟二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)
Query query = session.createQuery(“ from Student s”);
query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
session.close();
System.out.println(“------------------------------------------”);
………
Query query = session.createQuery(“ from Student s”);
query.setCacheable(true);
List students = query.list();
for(Iterator iter = students.iterate();iter.hasNext();){
Student stu = (Student)iter.next();
System.out.println(stu.getName());
}
第二不會發出sql,因為開啟了二級緩存和查詢緩存,查詢緩存緩存了實體對象的id列表,hibernate會根據實體對象的id列表到二級緩存中取得相應的數據