hibernate查询缓存

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

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

启用查询缓存:

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

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

只对list()方法起作用

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



实例

一、查询普通属性

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

代码:

Session session = this.sf.openSession();

List list = session.createQuery("select id from Order")

.setCacheable(true)

.list();

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



//session.close();

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



List l = session.createQuery("select id from Order")

.setCacheable(true)

.list();

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

session.close();

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

Hibernate:

select

order0_.id as col_0_0_

from

t_order order0_

数量:3

数量:3



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

代码同1

执行结果:

Hibernate:

select

order0_.id as col_0_0_

from

t_order order0_

数量:3

数量:3

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

代码:

Session session = this.sf.openSession();

List list = session.createQuery("select id from Order")

.setCacheable(false)

.list();

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



List l = session.createQuery("select id from Order")

.setCacheable(false)

.list();

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

session.close();

执行结果:

Hibernate:

select

order0_.id as col_0_0_

from

t_order order0_

数量:3

Hibernate:

select

order0_.id as col_0_0_

from

t_order order0_

数量:3

二、查询实体对象

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

代码:

public void test1(){

Session session = this.sf.openSession();

List list = session.createQuery("from Order")

.list();

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



List l = session.createQuery("from Order")

.list();

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

session.close();

}

执行结果:

Hibernate:

select

order0_.id as id1_,

order0_.orderNum as orderNum1_,

order0_.fk_user_id as fk3_1_

from

t_order order0_

数量:3

Hibernate:

select

order0_.id as id1_,

order0_.orderNum as orderNum1_,

order0_.fk_user_id as fk3_1_

from

t_order order0_

数量:3

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

代码:

Session session = this.sf.openSession();

List list = session.createQuery("from Order")

.setCacheable(true)

.list();

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



List l = session.createQuery("from Order")

.setCacheable(true)

.list();

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

session.close();

执行结果:

Hibernate:

select

order0_.id as id1_,

order0_.orderNum as orderNum1_,

order0_.fk_user_id as fk3_1_

from

t_order order0_

数量:3

数量:3

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

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

代码:

Session session = this.sf.openSession();

List list = session.createQuery("from Order")

.setCacheable(true)

.list();

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

session.close();

//第二个session

session = this.sf.openSession();

List l = session.createQuery("from Order")

.setCacheable(true)

.list();

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

session.close();

执行结果:

Hibernate:

select

order0_.id as id1_,

order0_.orderNum as orderNum1_,

order0_.fk_user_id as fk3_1_

from

t_order order0_

数量:3

Hibernate:

select

order0_.id as id1_0_,

order0_.orderNum as orderNum1_0_,

order0_.fk_user_id as fk3_1_0_

from

t_order order0_

where

order0_.id=?

Hibernate:

select

order0_.id as id1_0_,

order0_.orderNum as orderNum1_0_,

order0_.fk_user_id as fk3_1_0_

from

t_order order0_

where

order0_.id=?

Hibernate:

select

order0_.id as id1_0_,

order0_.orderNum as orderNum1_0_,

order0_.fk_user_id as fk3_1_0_

from

t_order order0_

where

order0_.id=?

数量:3

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



结论:

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

2.对实体对象的缓存集只缓存id
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值