【Hibernate】二级缓存(Hibernate默认使用的二级缓存)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35448976/article/details/77801991


一、Hibernate提供的缓存

有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!

 

二、一级缓存

基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!

特点:

作用范围较小! 缓存的事件短。

缓存效果不明显。

 

三、二级缓存

Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个换存也叫二级缓存。

Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。

如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。

四、二级缓存配置

查看hibernate.properties配置文件,二级缓存如何配置?

 

##########################

### Second-level Cache ###

##########################

 

#hibernate.cache.use_second_level_cache false【二级缓存默认不开启,需要手动开启】

#hibernate.cache.use_query_cache true      【开启查询缓存】

 

## choose a cache implementation 【二级缓存框架的实现】

 

#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider

#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider

hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默认实现

#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider

#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider

#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider

 

五、二级缓存,使用步骤

1) 开启二级缓存

2)指定缓存框架

3)指定那些类加入二级缓存,类要写全名

4)测试

测试二级缓存!

 

六、缓存策略

<class-cache usage="read-only"/>     放入二级缓存的对象,只读;

<class-cache usage="nonstrict-read-write"/>  非严格的读写

<class-cache usage="read-write"/>    读写; 放入二级缓存的对象可以读、写;

<class-cache usage="transactional"/>   (基于事务的策略)

 

 

七、集合缓存

<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->

<collection-cache 

usage="read-write" collection="cn.lfsenior.b_second_cache.Dept.emps"/>

 

八、查询缓存

list() 默认情况只会放入缓存,不会从一级缓存中取!

   使用查询缓存,可以让list()查询从二级缓存中取!

1、开启查询缓存后查询的list()可以从二级缓存中拿数据(list()不能从一级缓存[session缓存]中拿数据),但是不主动去拿,需要设置setCacheable(true)

Query q = session1.createQuery("from Dept").setCacheable(true);

System.out.println(q.list());

 

 

 

完整案例:

2、二级、集合缓存配置可以在*.hbm.xml文件也可以在*.cfg.xml中配置,一般推荐使用后者,便于统一维护

 Hibernate.cfg.xml

<!--****************** 【二级缓存配置】****************** -->
<!-- a.  开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- b. 指定使用哪一个缓存框架(默认提供的) -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!-- c. 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="cn.lfsenior.b_second_cache.Dept"/>
<class-cache usage="read-only" class="cn.lfsenior.b_second_cache.Employee"/>
<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
<collection-cache usage="read-write" collection="cn.lfsenior.b_second_cache.Dept.emps"/>

App  测试类

public class App {
private static SessionFactory sf;
static {
sf = new Configuration()
.configure()
.addClass(Dept.class)   
.addClass(Employee.class)   // 测试时候使用
.buildSessionFactory();
}
// 1. 测试二级缓存的使用
// 没有/有用 二级缓存
@Test
public void testCache() {
Session session1 = sf.openSession();
session1.beginTransaction();
// a. 查询一次
Dept dept = (Dept) session1.get(Dept.class, 10);
dept.getEmps().size();// 集合
session1.getTransaction().commit();
session1.close();
System.out.println("------");
// 第二个session
Session session2 = sf.openSession();
session2.beginTransaction();
// a. 查询一次
dept = (Dept) session2.get(Dept.class, 10);  // 二级缓存配置好; 这里不查询数据库
dept.getEmps().size();
session2.getTransaction().commit();
session2.close();
}
@Test
public void listCache() {
Session session1 = sf.openSession();
session1.beginTransaction();
// HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】
Query q = session1.createQuery("from Dept").setCacheable(true);
System.out.println(q.list());
session1.getTransaction().commit();
session1.close();
Session session2 = sf.openSession();
session2.beginTransaction();
q = session2.createQuery("from Dept").setCacheable(true);
System.out.println(q.list());  // 不查询数据库: 需要开启查询缓存
session2.getTransaction().commit();
session2.close();
}
}

也可在*.hbm.xml文件中配置

将当前类二级缓存(class节点下):

       <cache usage="read-only"/>

将当前类下的set集合加入集合缓存(set节点下):

       <cache usage="read-only"/>

<hibernate-mapping package="cn.lfsenior.entry" >
 
<class name="Dept" table="t_dept" >
<cache usage="read-only"/>
<id name="deptId">
<generator class="native" />
</id>
<property name="deptName" length="20"></property>
<!-- 1对多配置 -->
<set name="emps" >
<!-- 外键配置 -->
<cache usage="read-only"/>
<key column="dept_id"></key>
<one-to-many class="Employee"/>
</set>
    </class>
</hibernate-mapping>
 
展开阅读全文

没有更多推荐了,返回首页