Hibernate二级缓存:
二级缓存也称位进程级缓存或者sessionFactory级缓存,二级缓存可以被所有的session共享
二级缓存的配置和使用:
将echcache.xml(这个文件在hibernate代码包中的etc 目录下)拷贝到src目录下
开启二级缓存 修改hibernate.cfg.xml文件
<property name="hibernate.cache.use_second_level_cache">true</property>
指定缓存产品提供商,修改hibernate.cfg.xml文件
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
指定哪些类使用二级缓存:
在映射文件中采用<cache usage=""> 标签
在hibernate.cfg.xml中配置
<class-cache class="com.june.hibernate.Student" usage="read-only"/>
我推荐优先使用<read-only>
1. <read-only>
如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。
2. read/write
如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level), 那么就决不能使用这种缓存策略。如果在JTA环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_ class属性的值, 通过它,Hibernate才能知道该应用程序中JTA的TransactionManager的具体策略。 在其它环境中,你必须保证在Session.close() 、或Session.disconnect()调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate 内置的缓存策略并不支持锁定功能
3. nonstrict read/write
如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写 缓存策略。如果在JTA环境中使用该策略, 你必须为其指定hibernate.transaction.manager_lookup_class属性的值, 在其它环境中,你必须保证在 Session.close()、或Session.disconnect()调用前, 整个事务已经结束
二级缓存的是缓存实体对象的:
了解一级缓存的交互(session.setCacheMode())
主要是 CacheMode.NORMAL
CacheMode.PUT
CacheMode.GET
具体常见HibernateReference
有如下2个类 :
- public class Clazz {
- private Integer id;
- private String name;
- private Set<Student> students=new HashSet<Student>();
- }
- public class Student {
- private Integer id;
- private String name;
- private Clazz clazz;
public class Clazz {
private Integer id;
private String name;
private Set<Student> students=new HashSet<Student>();
}
public class Student {
private Integer id;
private String name;
private Clazz clazz;
}
映射文件为(我们对students类设置缓存):
- <class name="com.june.hibernate.Clazz" table="t_clazz">
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="name"></property>
- <set name="students" inverse="true">
- <key column="clazz"/>
- <one-to-many class="com.june.hibernate.Student"/>
- </set>
- </class>
- <class name="com.june.hibernate.Student" table="t_student">
- <!--
- <cache usage="read-only"/>-->
- <id name="id">
- <generator class="native"></generator>
- </id>
- <property name="name"></property>
- <many-to-one name="clazz" cascade="save-update"></many-to-one>
- </class>
<class name="com.june.hibernate.Clazz" table="t_clazz"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <set name="students" inverse="true"> <key column="clazz"/> <one-to-many class="com.june.hibernate.Student"/> </set> </class> <class name="com.june.hibernate.Student" table="t_student"> <!-- <cache usage="read-only"/>--> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <many-to-one name="clazz" cascade="save-update"></many-to-one> </class>
Hibernate 配置文件:
- <hibernate-configuration>
- <session-factory>
- <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_cache_level_2</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.connection.password">123456</property>
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <property name="hibernate.show_sql">true</property>
- <!-- 开启二级缓存 hibernate默认就是开启的 -->
- <property name="hibernate.cache.use_second_level_cache">true</property>
- <!-- 指定缓存产品提供商 -->
- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
- <mapping resource="com/june/hibernate/Clazz.hbm.xml"/>
- <mapping resource="com/june/hibernate/Student.hbm.xml"/>
- <!-- 我推荐在此设置二级缓存 而不是在具体的类配置文件中设置 因为在此设置会对非常清楚的了解 那些是设了二级缓存的 那些是没有设的-->
- <class-cache class="com.june.hibernate.Student" usage="read-only"/>
- </session-factory>
- </hibernate-configuration>
<hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_cache_level_2</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <!-- 开启二级缓存 hibernate默认就是开启的 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!-- 指定缓存产品提供商 --> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="com/june/hibernate/Clazz.hbm.xml"/> <mapping resource="com/june/hibernate/Student.hbm.xml"/> <!-- 我推荐在此设置二级缓存 而不是在具体的类配置文件中设置 因为在此设置会对非常清楚的了解 那些是设了二级缓存的 那些是没有设的--> <class-cache class="com.june.hibernate.Student" usage="read-only"/> </session-factory> </hibernate-configuration>
测试用例: