hibernate查询缓存

自:http://blog.sina.com.cn/s/blog_614cb62d0100fkp6.html

查询缓存的生命周期,当查询关联的表发生改变,那么查询缓存的生命周期结束(delete、update、modify)

启用查询缓存:

1.hibernate.cfg.xml中配置:<propertyname="cache.use_query_cache">true</property>

2.代码中用setCacheable(true)手动启用

只对list()方法起作用

默认情况下list()每次都会发SQL语句,只有配置了查询缓存它才会利用缓存。

实例

一、查询普通属性

1.查询普通属性,开启二级缓存和查询缓存,在同一个session中和不同session中

代码:

Sessionsession=this.sf.openSession();

Listlist=session.createQuery("selectidfromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+list.size());

//session.close();

//session=this.sf.openSession();

Listl=session.createQuery("selectidfromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+l.size());

session.close();

执行结果都一样,所以查询缓存的生命周期与session无关:

Hibernate:

select

order0_.idascol_0_0_

from

t_orderorder0_

数量:3

数量:3

2.查询普通属性,关闭二级缓存,开启查询缓存,在同一个session中

代码同1

执行结果:

Hibernate:

select

order0_.idascol_0_0_

from

t_orderorder0_

数量:3

数量:3

3.查询普通属性,开启二级缓存,关闭查询缓存,在同一个session中

代码:

Sessionsession=this.sf.openSession();

Listlist=session.createQuery("selectidfromOrder")

.setCacheable(false)

.list();

System.out.println("数量:"+list.size());

Listl=session.createQuery("selectidfromOrder")

.setCacheable(false)

.list();

System.out.println("数量:"+l.size());

session.close();

执行结果:

Hibernate:

select

order0_.idascol_0_0_

from

t_orderorder0_

数量:3

Hibernate:

select

order0_.idascol_0_0_

from

t_orderorder0_

数量:3

二、查询实体对象

1.关闭二级缓存和查询缓存,在同一个session中

代码:

publicvoidtest1(){

Sessionsession=this.sf.openSession();

Listlist=session.createQuery("fromOrder")

.list();

System.out.println("数量:"+list.size());

Listl=session.createQuery("fromOrder")

.list();

System.out.println("数量:"+l.size());

session.close();

}

执行结果:

Hibernate:

select

order0_.idasid1_,

order0_.orderNumasorderNum1_,

order0_.fk_user_idasfk3_1_

from

t_orderorder0_

数量:3

Hibernate:

select

order0_.idasid1_,

order0_.orderNumasorderNum1_,

order0_.fk_user_idasfk3_1_

from

t_orderorder0_

数量:3

2.关闭二级缓存,开启查询缓存,在同一个session中

代码:

Sessionsession=this.sf.openSession();

Listlist=session.createQuery("fromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+list.size());

Listl=session.createQuery("fromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+l.size());

session.close();

执行结果:

Hibernate:

select

order0_.idasid1_,

order0_.orderNumasorderNum1_,

order0_.fk_user_idasfk3_1_

from

t_orderorder0_

数量:3

数量:3

之所以第二次不发出SQL语句,是因为在同一个session中,实体对象保存到了一级缓存中;而查询缓存中保存了实体对象的id列表,第二次查询就根据id从一级缓存中取得数据。开启二级缓存,开启查询缓存,在不同session中也是这样的结果,只是实体对象保存到了二级缓存中,第二次查询从二级缓存中去找。

3.关闭二级缓存,开启查询缓存,在两个session中

代码:

Sessionsession=this.sf.openSession();

Listlist=session.createQuery("fromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+list.size());

session.close();

//第二个session

session=this.sf.openSession();

Listl=session.createQuery("fromOrder")

.setCacheable(true)

.list();

System.out.println("数量:"+l.size());

session.close();

执行结果:

Hibernate:

select

order0_.idasid1_,

order0_.orderNumasorderNum1_,

order0_.fk_user_idasfk3_1_

from

t_orderorder0_

数量:3

Hibernate:

select

order0_.idasid1_0_,

order0_.orderNumasorderNum1_0_,

order0_.fk_user_idasfk3_1_0_

from

t_orderorder0_

where

order0_.id=?

Hibernate:

select

order0_.idasid1_0_,

order0_.orderNumasorderNum1_0_,

order0_.fk_user_idasfk3_1_0_

from

t_orderorder0_

where

order0_.id=?

Hibernate:

select

order0_.idasid1_0_,

order0_.orderNumasorderNum1_0_,

order0_.fk_user_idasfk3_1_0_

from

t_orderorder0_

where

order0_.id=?

数量:3

这种情况下,当第二次查询执行的时候,在二级缓存和一级缓冲中都找不到实体对象,所以list()只有拿着id到数据库中一个一个找,于是产生了N+1问题。

结论:

1.查询缓存是对普通属性结果集的缓存

2.对实体对象的缓存集只缓存id

相关推荐