前两篇博客介绍了一级和二级缓存,他们都是缓存实体对象的,这个博客介绍一下查询缓存,缓存普通属性结果集比较难确定,它是当关联的表发生秀改,是指查询缓存的生命周期结束。
配置:
修改hibernate.cfg.xml,来开启查询缓存,默认false是不起作用的
<property name =“hibernate.cache.use_query_cache”> true </ property>
代码部分:
必须在程序中启用query.setCacheable(true),进行显示的调用开启查询缓存。
测试类:
(1)开启查询,关闭二级缓存,在一个会话中采用query.list()查询普通属性。第二次查询不会发出查询语句,因为启用查询缓
/ **
*开启查询,关闭二级缓存,采用query.list()查询普通属性
*:
*在一个会话中发查询
* /
public void testCache1(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
List name = session.createQuery(“select s.name from Student s”)。setCacheable(true).list();
for(int i = 0; i <names.size(); i ++){
String name =(String)names.get(i);
System.out.println(name);
}}
System.out.println(“------------------------”);
//不会发出查询语句,因为启用查询缓存
names = session.createQuery(“select s.name from Student s”)。setCacheable(true).list();
for(int i = 0; i <names.size(); i ++){
String name =(String)names.get(i);
System.out.println(name);
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
(2)开启查询,开启二级缓存,在两个会话中采用query.list()查询普通属性,不会发出查询语句,因为查询缓存和会话的生命周期没有关系。
/ **
*开启查询,开启二级缓存,采用query.list()查询普通属性
*:
*在两个会话中发查询
* /
public void testCache2(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
List name = session.createQuery(“select s.name from Student s”)。setCacheable(true).list();
for(int i = 0; i <names.size(); i ++){
String name =(String)names.get(i);
System.out.println(name);
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
System.out.println(“------------------------------------------- ------------“);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//不会发出查询语句,因为查询缓存和session的生命周期没有关系
List names = session.createQuery(“select s.name from Student s”)
.setCacheable(true)
.list();
for(int i = 0; i <names.size(); i ++){
String name =(String)names.get(i);
System.out.println(name);
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
}}
(3)开启查询,关闭二级缓存,在两个会话中采用query.iterator()查询普通属性,发出查询语句,query.iterator()查询普通属性它不会使用查询缓存,查询缓存只对query.list()起作用。
/ **
*开启查询,关闭二级缓存,采用query.iterator()查询普通属性
*:
*在两个会话中发query.iterator()查询
* /
public void testCache3(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
Iterator iter = session.createQuery(“select s.name from Student s”)setCacheable(true).iterate();
while(iter.hasNext()){
String name =(String)iter.next();
System.out.println(name);
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
System.out.println(“------------------------------------------- ------------“);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//会发出查询语句,query.iterator()查询普通属性它不会使用查询缓
//查询缓存只对query.list()起作用
Iterator iter = session.createQuery(“select s.name from Student s”)setCacheable(true).iterate();
while(iter.hasNext()){
String name =(String)iter.next();
System.out.println(name);
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
(4)关闭查询,关闭二级缓存,在两个会话中采用query.list()查询实体,发出查询语句,默认query.list()每次执行都会发出查询语句。
/ **
*关闭查询,关闭二级缓存,采用query.list()查询实体
*:
*在两个会话中发查询
* /
public void testCache4(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
List students = session.createQuery(“select s from Student s”)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
System.out.println(“------------------------------------------- ------------“);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//会发出查询语句,默认query.list()每次执行都会发出查询语句
List students = session.createQuery(“select s from Student s”)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
}}
(5)开启查询,关闭二级缓存,在两个会话中采用query.list()查询实体,会发出ñ 条查询语句,应为开启了查询缓存,关闭了二级缓存,那么查询缓存就会缓存实体对象的ID,第二次执行query.list(),将查询缓存中的ID 一次取出,分别到一级缓存和二级缓存中查询相应的对象,如果存在就使用缓存中的实体对象,否则根据ID 发出查询学生的语句。
/ **
*开启查询,关闭二级缓存,采用query.list()查询实体
*:
*在两个会话中发查询
* /
public void testCache5(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
List students = session.createQuery(“select s from Student s”)
.setCacheable(true)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
System.out.println(“------------------------------------------- ------------“);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//会发出n条查询语句,因为开启了查询缓存,关闭了二级缓存,那么查询缓存就会缓存实体对象的id
//第二次执行query.list(),将查询缓存中的id依次取出,分别到一级缓存和二级缓存中查询相应的实体
//对象,如果存在就使用缓存中的实体对象,否则根据id发出查询学生的语句
List students = session.createQuery(“select s from Student s”)
.setCacheable(true)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
}}
(6)开启查询,开启二级缓存,两个会议中发query.list()查询。不发出查询语句,因为配置了二级缓存和查询缓存
/ **
*开启查询,开启二级缓存,采用query.list()查询实体
*:
*在两个会话中发查询
* /
public void testCache6(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
List students = session.createQuery(“select s from Student s”)
.setCacheable(true)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
System.out.println(“------------------------------------------- ------------“);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//不再发出查询语句,因为配置了二级缓存和查询缓存
List students = session.createQuery(“select s from Student s”)
.setCacheable(true)
.list();
for(int i = 0; i <students.size(); i ++){
学生studnet =(学生)students.get(i);
System.out.println(studnet.getName());
}}
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
} finally {
HibernateUtils.closeSession(session);
}}
}}
}}
小结:
如果查询普通属性,会先到查询缓存中取,如果没有查询数据库;如果查询实体,会先到查询缓存中取ID,如果有,则根据ID到缓存中取实体,如果缓存中娶不到实体,再查询数据库。