在hibernate的使用中,大家多數時(shí)間都在討論一級緩存和二級緩存,而往往忽略了查詢(xún)緩存。其實(shí)hibernate的查詢(xún)緩存在使用過(guò)程中也起著(zhù)同樣重要的作用。hibernate的查詢(xún)緩存是主要是針對普通屬性結果集的緩存, 而對于實(shí)體對象的結果集只緩存id。在一級緩存,二級緩存和查詢(xún)緩存都打開(kāi)的情況下作查詢(xún)操作時(shí)這樣的:查詢(xún)普通屬性,會(huì )先到查詢(xún)緩存中取,如果沒(méi)有,則查詢(xún)數據庫;查詢(xún)實(shí)體,會(huì )先到查詢(xún)緩存中取id,如果有,則根據id到緩存(一級/二級)中取實(shí)體,如果緩存中取不到實(shí)體,再查詢(xún)數據庫。
和一級/二級緩存不同,查詢(xún)緩存的生命周期 ,是不確定的,當前關(guān)聯(lián)的表發(fā)生改變時(shí),查詢(xún)緩存的生命周期結束。
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 開(kāi)啟查詢(xún)緩存,關(guān)閉二級緩存, 開(kāi)啟一個(gè)session,分別調用query.list
*/
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
/*
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
List<String> names = query.list();
for (Iterator<String> it = names.iterator(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
System.out.println("================================");
query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
//沒(méi)有發(fā)出查詢(xún)語(yǔ)句,因為這里使用的查詢(xún)緩存
names = query.list();
for (Iterator<String> it = names.iterator(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}*/
/* @SuppressWarnings("unchecked")
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 開(kāi)啟查詢(xún)緩存,關(guān)閉二級緩存, 開(kāi)啟兩個(gè)session,分別調用query.list
*//*
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
//query.setCacheable(true);
List<String> names = query.list();
for (Iterator<String> it = names.iterator(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
System.out.println("================================");
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
//query.setCacheable(true);
//不會(huì )發(fā)出查詢(xún)語(yǔ)句,因為查詢(xún)緩存和session無(wú)關(guān).
List<String> names = query.list();
for (Iterator<String> it = names.iterator(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}*/
/* @SuppressWarnings("unchecked")
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 開(kāi)啟查詢(xún)緩存,關(guān)閉二級緩存, 開(kāi)啟兩個(gè)session,分別調用query.iterate
*//*
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
for (Iterator<String> it = query.iterate(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
System.out.println("================================");
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
//會(huì )發(fā)出查詢(xún)語(yǔ)句,因為query.iterate不使用查詢(xún)緩存
for (Iterator<String> it = query.iterate(); it.hasNext();) {
String name = it.next();
System.out.println(name);
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}*/
/* @SuppressWarnings("unchecked")
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 關(guān)閉查詢(xún)緩存,關(guān)閉二級緩存, 開(kāi)啟兩個(gè)session,分別調用query.list查詢(xún)實(shí)體對象
*//*
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
//query.setCacheable(true);
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
System.out.println("================================");
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
//query.setCacheable(true);
//會(huì )發(fā)出查詢(xún)語(yǔ)句,因為list默認每次都會(huì )發(fā)出sql語(yǔ)句
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}*/
/* @SuppressWarnings("unchecked")
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 開(kāi)啟查詢(xún)緩存,關(guān)閉二級緩存, 開(kāi)啟兩個(gè)session,分別調用query.list查詢(xún)實(shí)體對象
*//*
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
System.out.println("================================");
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
//會(huì )發(fā)出根據id查詢(xún)實(shí)體的n條查詢(xún)語(yǔ)句,因為這種情況下,查詢(xún)過(guò)程是這樣的:
// 在第一次執行list時(shí),會(huì )把查詢(xún)對象的id緩存到查詢(xún)緩存里
// 第二次執行list時(shí), 會(huì )遍歷查詢(xún)緩存里的id到緩存里去找實(shí)體對象,由于這里沒(méi)找到實(shí)體對象,
//所以就發(fā)出n條查詢(xún)語(yǔ)句到數據庫中查詢(xún).
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}*/
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Session session = null;
Transaction t = null;
/**
* 開(kāi)啟查詢(xún)緩存,開(kāi)啟二級緩存, 開(kāi)啟兩個(gè)session,分別調用query.list查詢(xún)實(shí)體對象
*/
//如果不用查詢(xún)緩存的話(huà),那兩個(gè)都發(fā)出查詢(xún)語(yǔ)句,這也是默認的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
System.out.println("================================");
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢(xún)緩存
query.setCacheable(true);
//不會(huì )發(fā)出查詢(xún)語(yǔ)句,因為這種情況下,查詢(xún)過(guò)程是這樣的:
// 在第一次執行list時(shí),會(huì )把查詢(xún)對象的id緩存到查詢(xún)緩存里
// 第二次執行list時(shí), 會(huì )遍歷查詢(xún)緩存里的id到緩存里去找實(shí)體對象,由于這里開(kāi)啟了二級緩存,可以找到目標實(shí)體對象,
//所以就不會(huì )再發(fā)出n條查詢(xún)語(yǔ)句.
List<Student> students = query.list();
for (Iterator<Student> it = students.iterator(); it.hasNext();) {
Student s = it.next();
System.out.println(s.getName());
}
t.commit();
} catch (Exception e) {
e.printStackTrace();
t.rollback();
} finally {
HibernateUtils.closeSession(session);
}
}