二级缓存
数据特点
1、公共的数据
2、不经常修改的数据
3、私密性不是很高的数据
结构
二级缓存的生命周期
当hibernate程序开始的时候,二级缓存就存在了,当hibernate容器销毁的时候,二级缓存就销毁了。hibernate内部没有提供二级缓存的实现 默认情况下,利用的是ehcache。
开启缓存对配置文件进行设置
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个sessionFactory就代表一个数据库的描述
-->
<session-factory>
<!-- 链接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 链接数据库的密码 -->
<property name="connection.password">1234</property>
<!-- 链接数据库的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 链接数据库的url -->
<property name="connection.url">
jdbc:mysql://localhost:3306/itheima??characterEncoding=UTF-8
</property>
<!--
方言
告诉hibernate用什么样的数据库,将来会生成什么样的sql语句
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
hibernate对表的策略
validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表
create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表
create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表
update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表
-->
<property name="hbm2ddl.auto">update</property>
<!--
开启二级缓存
-->
<property name="cache.use_second_level_cache">true</property>
<!--
二级缓存的供应商
-->
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--
开启了类级别的二级缓存
usage 二级缓存的缓存策略
read-only
可以把一个对象放入到二级缓存中,但是不能修改
read-write
可以把一个对象放入到二级缓存中,可以读可以改
class 类的全名
-->
<!--
<class-cache usage="read-only" class="com.itheima11.hibernate.sessionfactory.domain.Classes"/>
-->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="current_session_context_class">thread</property>
<!--开启二级缓存的统计机制-->
<property name="generate_statistics">true</property>
<mapping
resource="com/sanmao/utils/Classes.hbm.xml" />
<mapping
resource="com/sanmao/utils/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.sanmao.utils.Classes">
<cache usage="read-only"></cache>
<id name="cid" type="java.lang.Long">
<column name="cid" />
<generator class="increment" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="20" />
</property>
<property name="description" type="java.lang.String">
<column name="description" length="50" />
</property>
<set name="students" inverse="true">
<key>
<column name="cid" />
</key>
<one-to-many class="com.sanmao.utils.Student" />
</set>
</class>
</hibernate-mapping>
对各种方法的测试
public class SessionFactoryTest {
/**
* 对声明支持二级缓存的 持久化类, session的get方法
* 将其放入到二级缓存中
* 查询数据,先从一级缓存中查询数据,没有再去二级缓存中查询数据,
* 最后从数据库查询数据
* */
@Test
public void testGet(){
Configuration configuration=new Configuration();
configuration.configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
Classes classes1=(Classes)session.get(Classes.class,1L);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.close();//一级缓存消失,一级缓存的生命周期随着session的生命周期
session=sessionFactory.openSession();
Classes classes2=(Classes)session.get(Classes.class,1L);
session.close();
}
/**
* Save() 方法不能把对象放入到二级缓存中
* 经过测试update也不可以把对象放入到二级缓存中
* */
@Test
public void testSave(){
Configuration configuration=new Configuration();
configuration.configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction();
Classes classes=new Classes();
classes.setName("asdasd");
session.save(classes);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
transaction.commit();
session.close();
session=sessionFactory.openSession();
Classes classes1=(Classes)session.get(Classes.class,1L);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
}
/**
* 说明evict 方法,只是清除一级缓存
* */
@Test
public void testEvict(){
Configuration configuration=new Configuration();
configuration.configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction();
Classes classes=(Classes)session.get(Classes.class,1L);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.evict(classes);
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
transaction.commit();
session.close();
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
}
/**
* list方法
* 可以把对象放入二级缓存中
* */
@Test
public void testList(){
Configuration configuration=new Configuration();
configuration.configure();
SessionFactory sessionFactory=configuration.buildSessionFactory();
Session session=sessionFactory.openSession();
session.createQuery("from com.sanmao.utils.Classes").list();
System.out.println(sessionFactory.getStatistics().getEntityLoadCount());
session.close();
}
}