在hibernate的使用中,大家多數(shù)時(shí)間都在討論一級(jí)緩存和二級(jí)緩存,而往往忽略了查詢緩存。其實(shí)hibernate的查詢緩存在使用過程中也起著同樣重要的作用。hibernate的查詢緩存是主要是針對(duì)普通屬性結(jié)果集的緩存, 而對(duì)于實(shí)體對(duì)象的結(jié)果集只緩存id。在一級(jí)緩存,二級(jí)緩存和查詢緩存都打開的情況下作查詢操作時(shí)這樣的:查詢普通屬性,會(huì)先到查詢緩存中取,如果沒有,則查詢數(shù)據(jù)庫;查詢實(shí)體,會(huì)先到查詢緩存中取id,如果有,則根據(jù)id到緩存(一級(jí)/二級(jí))中取實(shí)體,如果緩存中取不到實(shí)體,再查詢數(shù)據(jù)庫。
和一級(jí)/二級(jí)緩存不同,查詢緩存的生命周期 ,是不確定的,當(dāng)前關(guān)聯(lián)的表發(fā)生改變時(shí),查詢緩存的生命周期結(jié)束。
public static void main(String[] args) {
Session session = null;
Transaction t = null;
*//**
* 開啟查詢緩存,關(guān)閉二級(jí)緩存, 開啟一個(gè)session,分別調(diào)用query.list
*/
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
/*
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢緩存
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");
//啟用查詢緩存
query.setCacheable(true);
//沒有發(fā)出查詢語句,因?yà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;
*//**
* 開啟查詢緩存,關(guān)閉二級(jí)緩存, 開啟兩個(gè)session,分別調(diào)用query.list
*//*
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢緩存
//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");
//啟用查詢緩存
//query.setCacheable(true);
//不會(huì)發(fā)出查詢語句,因?yàn)椴樵兙彺婧蛃ession無關(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;
*//**
* 開啟查詢緩存,關(guān)閉二級(jí)緩存, 開啟兩個(gè)session,分別調(diào)用query.iterate
*//*
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s.name from Student s");
//啟用查詢緩存
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");
//啟用查詢緩存
query.setCacheable(true);
//會(huì)發(fā)出查詢語句,因?yàn)閝uery.iterate不使用查詢緩存
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)閉查詢緩存,關(guān)閉二級(jí)緩存, 開啟兩個(gè)session,分別調(diào)用query.list查詢實(shí)體對(duì)象
*//*
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢緩存
//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");
//啟用查詢緩存
//query.setCacheable(true);
//會(huì)發(fā)出查詢語句,因?yàn)閘ist默認(rèn)每次都會(huì)發(fā)出sql語句
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;
*//**
* 開啟查詢緩存,關(guān)閉二級(jí)緩存, 開啟兩個(gè)session,分別調(diào)用query.list查詢實(shí)體對(duì)象
*//*
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢緩存
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");
//啟用查詢緩存
query.setCacheable(true);
//會(huì)發(fā)出根據(jù)id查詢實(shí)體的n條查詢語句,因?yàn)檫@種情況下,查詢過程是這樣的:
// 在第一次執(zhí)行l(wèi)ist時(shí),會(huì)把查詢對(duì)象的id緩存到查詢緩存里
// 第二次執(zhí)行l(wèi)ist時(shí), 會(huì)遍歷查詢緩存里的id到緩存里去找實(shí)體對(duì)象,由于這里沒找到實(shí)體對(duì)象,
//所以就發(fā)出n條查詢語句到數(shù)據(jù)庫中查詢.
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;
/**
* 開啟查詢緩存,開啟二級(jí)緩存, 開啟兩個(gè)session,分別調(diào)用query.list查詢實(shí)體對(duì)象
*/
//如果不用查詢緩存的話,那兩個(gè)都發(fā)出查詢語句,這也是默認(rèn)的情況.
try {
session = HibernateUtils.getSession();
t = session.beginTransaction();
Query query = session.createQuery("select s from Student s");
//啟用查詢緩存
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");
//啟用查詢緩存
query.setCacheable(true);
//不會(huì)發(fā)出查詢語句,因?yàn)檫@種情況下,查詢過程是這樣的:
// 在第一次執(zhí)行l(wèi)ist時(shí),會(huì)把查詢對(duì)象的id緩存到查詢緩存里
// 第二次執(zhí)行l(wèi)ist時(shí), 會(huì)遍歷查詢緩存里的id到緩存里去找實(shí)體對(duì)象,由于這里開啟了二級(jí)緩存,可以找到目標(biāo)實(shí)體對(duì)象,
//所以就不會(huì)再發(fā)出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);
}
}