一、缓存的概念:                                                

以空间换时间;
 
二、Hibernate缓存的分类:                                        
前面我们讲的缓存都是session缓存;也叫一级缓存;get,load等缓存都是内置的,一级缓存;
SessionFactory缓存,二级缓存;

这里以Class —— Student,1对多的关系(单向)来例子说明下:

Class.java:

package com.cy.model;

public class Class {
private int id;
private String name; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} }

Student.java:

package com.cy.model;

import com.cy.model.Class;

public class Student {
private int id;
private String name;
private Class c; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class getC() {
return c;
}
public void setC(Class c) {
this.c = c;
} }

Class.hbm.xml:

<hibernate-mapping package="com.cy.model">

    <class name="Class" table="t_class">
<id name="id" column="classId">
<generator class="native"></generator>
</id>
<property name="name" column="className"></property>
</class> </hibernate-mapping>

Student.hbm.xml:

<hibernate-mapping package="com.cy.model">

    <class name="Student" table="t_student">
<id name="id" column="stuId">
<generator class="native"></generator>
</id>
<property name="name" column="stuName"></property> <many-to-one name="c" class="com.cy.model.Class" column="classId" cascade="save-update"></many-to-one>
</class> </hibernate-mapping>

StudentTest.java:

package com.cy.service;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.cy.model.Class;
import com.cy.util.HibernateUtil; public class StudentTest { private SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
private Session session; @Before
public void setUp() throws Exception {
session=sessionFactory.openSession();
session.beginTransaction();
} @After
public void tearDown() throws Exception {
session.getTransaction().commit();
session.close();
} /**
* 同一个session中,同一个事务是有一级缓存的;
*/
@Test
public void testCache1(){
Class c = (Class) session.get(Class.class, 1);
System.out.println(c.getName()); Class c2 = (Class) session.get(Class.class, 1);
System.out.println(c2.getName());
System.out.println(c == c2); /*
* Hibernate: select class0_.classId as classId1_0_0_, class0_.className as classNam2_0_0_ from t_class class0_ where class0_.classId=?
08计算机本科
08计算机本科
true 第一次取c1的时候,已经将取出来的数据c1放到缓存中。
第二次取c2的时候,是有session缓存的。首选从缓存中找,找到,直接从缓存中拿,而不到数据库中去取了。
两个是同一个OID对象;
*/
} /**
* 在不同的事务中,是否有缓存?
*/
@Test
public void testCache2(){
Session session1 = sessionFactory.openSession();
session1.beginTransaction();
Class c = (Class) session1.get(Class.class, 1);
System.out.println(c.getName());
session1.getTransaction().commit();
session1.close(); Session session2 = sessionFactory.openSession();
session2.beginTransaction();
Class c2 = (Class) session2.get(Class.class, 1);
System.out.println(c2.getName());
session2.getTransaction().commit();
session2.close(); System.out.println(c == c2);
/*
* Hibernate: select class0_.classId as classId1_0_0_, class0_.className as classNam2_0_0_ from t_class class0_ where class0_.classId=?
08计算机本科
Hibernate: select class0_.classId as classId1_0_0_, class0_.className as classNam2_0_0_ from t_class class0_ where class0_.classId=?
08计算机本科
false 虽然在同一个session中有缓存,但是这里新开辟了一个事务,发出两个sql
不同的事务是不能共用一级缓存的。
一级缓存只适用于同一个session,同一个事务;
*/
}
}

三、二级缓存策略提供商:                                          

配置ehcache二级缓存,让不同的session,不同的事务能共享数据。
要用到SessionFactory缓存了;
 
使用到的ehcache相关的jar包:

jar包在hibernate压缩包中:
hibernate-release-4.3.5.Final\lib\optional\ehcache
可以参考hibernate压缩包中的hibernate-ehcache的配置:
hibernate-release-4.3.5.Final\project\hibernate-ehcache\bin
hibernate-release-4.3.5.Final\project\hibernate-ehcache\bin\hibernate-config\ehcache.xml 以及hibernate.cfg.xml
 
代码实现:
1)ehcache.xml配置:
<ehcache>

       <!-- 指定一个文件目录,当EHCache把数据写到硬盘上时,将把数据写到这个目录下 -->
<diskStore path="E:\\ehcache"/> <!--
设置缓存的默认数据过期策略
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/> <!--
name 设置缓存的名字,他的取值为类的完整名字或者类的集合的名字;
maxElementsInMemory 设置基于内存的缓存可存放的对象的最大数目
eternal 如果为true,表示对象永远不会过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds,默认为false;
timeToIdleSeconds 设定允许对象处于空闲状态的最长时间,以秒为单位;
timeToLiveSeconds 设定对象允许存在于缓存中的最长时间,以秒为单位;
overflowToDisk 如果为true,表示当基于内存的缓存中的对象数目达到maxElementsInMemory界限,会把溢出的对象写到基于硬盘的缓存中;
--> <!-- 设定具体的第二级缓存的数据过期策略 -->
<cache name="com.cy.model.Class"
maxElementsInMemory="1"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/> </ehcache>

2)hibernate.cfg.xml中相关ehcache二级缓存的配置:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!--数据库连接设置 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property> <!-- 方言 -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 控制台显示SQL -->
<property name="show_sql">true</property> <!-- 自动更新表结构 -->
<property name="hbm2ddl.auto">update</property> <!-- 启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 配置使用的二级缓存的产品 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<!-- 配置启用查询缓存 -->
<property name="cache.use_query_cache">true</property>
<property name="net.sf.ehcache.configurationResourceName">ehcache.xml</property> <mapping resource="com/cy/model/Student.hbm.xml"/>
<mapping resource="com/cy/model/Class.hbm.xml"/>
</session-factory> </hibernate-configuration>

3)最后,Class.hbm.xml中配置使用cache:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.cy.model"> <class name="Class" table="t_class">
<cache usage="read-only"/>
<id name="id" column="classId">
<generator class="native"></generator>
</id>
<property name="name" column="className"></property>
</class> </hibernate-mapping>

4)测试代码:

/**
* 配置了二级缓存ehcache后,再次进行测试:
*/
@Test
public void testCache3(){
Session session1 = sessionFactory.openSession();
session1.beginTransaction();
Class c = (Class) session1.get(Class.class, 1);
System.out.println(c.getName());
session1.getTransaction().commit();
session1.close(); Session session2 = sessionFactory.openSession();
session2.beginTransaction();
Class c2 = (Class) session2.get(Class.class, 1);
System.out.println(c2.getName());
session2.getTransaction().commit();
session2.close(); System.out.println(c == c2);
/*
* Hibernate: select class0_.classId as classId1_0_0_, class0_.className as classNam2_0_0_ from t_class class0_ where class0_.classId=?
08计算机本科
08计算机本科
false 只有1条sql,说明在第2次查的时候,使用到了二级缓存。
*/ }

四、什么数据适合放二级缓存中                                    

一般这些信息都是只读;不能修改;
 
 
 

Hibernate学习11——配置Hibernate二级缓存的更多相关文章

  1. Hibernate学习(九)———— 二级缓存和事务级别详讲

    序言 这算是hibernate的最后一篇文章了,下一系列会讲解Struts2的东西,然后说完Struts2,在到Spring,然后在写一个SSH如何整合的案例.之后就会在去讲SSM,在之后我自己的个人 ...

  2. Hibernate JPA 中配置Ehcache二级缓存

    在Hibernate3 JPA里配置了一下非分布式环境的二级缓存,效果不错.具体过程如下: 1, 需要引入的jar包 http://ehcache.org/downloads/catalog 下载的包 ...

  3. [原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. Hibernate学习笔记(六) — Hibernate的二级缓存

    我们知道hibernate的一级缓存是将数据缓存到了session中从而降低与数据库的交互.那么二级缓存呢? 一.应用场合 比方.在12306购票时.须要选择出发地与目的地,假设每点一次都与数据库交互 ...

  5. 03_MyBatis基本查询,mapper文件的定义,测试代码的编写,resultMap配置返回值,sql片段配置,select标签标签中的内容介绍,配置使用二级缓存,使用别名的数据类型,条件查询ma

     1 PersonTestMapper.xml中的内容如下: <?xmlversion="1.0"encoding="UTF-8"?> < ...

  6. Hibernate学习一:Hibernate注解CascadeType

    http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...

  7. mybatis学习:mybatis的二级缓存

    一级缓存: 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据.不同的sqlSession ...

  8. Hibernate学习11——Hibernate 高级配置(连接池、log4j)

    第一节:配置数据库连接池 这里配置c3p0连接池,需要的jar包: jar包位于hibernate压缩包的:hibernate-release-4.3.5.Final\lib\optional\c3p ...

  9. JPA学习笔记(11)——使用二级缓存

    一级缓存 查询两次id为1的user User user1 = entityManager.find(User.class, 1); User user2 = entityManager.find(U ...

随机推荐

  1. linux FTP 操作

    1.登陆: ftp 172.xxx.xxx.xxx 按提示输入用户名和密码 2.上传: 单个文件:put /路径/文件名 批量: 输入 prom 此命令是关闭交互(否则总是询问你是否要上传) 输入下载 ...

  2. iOS 开发经验总结

    iOS 开发经验总结http://www.cocoachina.com/ios/20170216/18699.html 1.cocoa pods 常用的framework 1 2 3 4 5 6 7 ...

  3. 《Effective C++》第3章 资源管理(1)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  4. Linux:expand命令详解

    expand 用于将文件的制表符[TAB]转换为空格,将结果显示到标准输出设备 语法 expand(选项)(file) 选项 -t<数字>:指定制表符所代表的空白字符的个数,而不使用默认的 ...

  5. Getting command line access to PHP and MySQL running MAMP on OSX

    建立自己profile路径应该在/Users/yourname/,最后要运行. ./.profile使文件生效,和windows中给添加环境变量是一个道理,还可以看出linux和UNIX默认运行路径为 ...

  6. css 添加伪元素 消除浮动 对父元素高度产生的影响

  7. HDU 1073

    http://acm.hdu.edu.cn/showproblem.php?pid=1073 模拟oj判题 随便搞,开始字符串读入的细节地方没处理好,wa了好久 #include <iostre ...

  8. java未来发展方向!新手入门了解

    随社会信息的发展着,java广泛应用于PC.数据中心.游戏控制台.科学超级计算机.移动电话和互联网等行业.从目前的招聘量上看,对java开发人才需求量是很大的,而且未来的仍然是主流,就业前景很好.只要 ...

  9. Sqlalchemy 设置表编码及引擎

    1. 设置引擎编码方式为utf8. engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?ch ...

  10. MpVue开发之组件引入的问题

    再一次开发订餐系统中,遇到订餐页面引入头部商品列表,底部组件时,报错,模块编译失败,未进入缓存区. 我以为是新添加的模块没有重新启动导致的,然后重新与运行npm run dev后还是失败, 最后经过反 ...