二级缓存 对数据查询
二级缓存:存放公有数据
1、适用场合:
1、数据不能频繁更新
2、数据能公开,私密性不是很强
2、hibernate本身并没有提供二级缓存的解决方案
3、二级缓存的实现是依赖于第三方供应商完成的
ehcache
oscache
jbosscache
swamchache
4、二级缓存的操作
1、二级缓存存在sessionFactory中
2、生命周期:与sessionFactory保持一致
3、使用二级缓存的步骤
1、在hibernate.cfg.xml
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
2、让某一个对象进入到二级缓存中(以下选一种配置方式,推荐第二种)
* 在配置文件中
<class-cache usage="read-only" class="cn.itcast.hiberate.sh.domain.Classes"/>
* 在映射文件中
<cache usage="read-only"/>
3、使用
session.get/session.load
5、查询缓存
在二级缓存的基础上 在cfg.xml加上
<property name="cache.use_query_cache">true</property>,只能在session.createQuery()中使用
示例:
hibernate.cfg.xml
1 <?xml version='1.0' encoding='utf-8'?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6 <!-- 7 一个session-factory只能连接一个数据库 8 --> 9 <session-factory> 10 <!-- 11 数据库的用户名 12 --> 13 <property name="connection.username">root</property> 14 <!-- 15 密码 16 --> 17 <property name="connection.password">root</property> 18 <!-- 19 url 20 --> 21 <property name="connection.url"> 22 jdbc:mysql://localhost:3306/itcast_sh_hibernate 23 </property> 24 <!-- 25 作用:根据持久化类和映射文件生成表 26 validate 27 create-drop 28 create 29 update 30 --> 31 <property name="hbm2ddl.auto">update</property> 32 <!-- 33 显示hibernate内部生成的sql语句 34 --> 35 <property name="show_sql">true</property> 36 <property name="format_sql">true</property> 37 <!-- 38 告诉hibernate,session由当前线程产生 39 --> 40 <property name="current_session_context_class">thread</property> 41 42 <!-- 43 开启二级缓存 44 --> 45 <property name="cache.use_second_level_cache">true</property> 46 47 <!-- 48 二级缓存的提供商 49 --> 50 <property name="cache.provider_class"> 51 org.hibernate.cache.EhCacheProvider 52 </property>
<!--查询缓存,用于createQuery代码-->
53 <property name="cache.use_query_cache">true</property> 54 55 <mapping resource="cn/itcast/hiberate/sh/domain/Classes.hbm.xml" /> 56 57 <!-- 58 <class-cache usage="read-only" class="cn.itcast.hiberate.sh.domain.Classes"/> 59 --> 60 </session-factory> 61 </hibernate-configuration>
Classes.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package cn.itcast.hiberate.sh.domain; 2 3 import java.io.Serializable; 4 import java.util.Set; 5 6 public class Classes implements Serializable{ 7 private Long cid; 8 private String cname; 9 private String description; 10 11 public Long getCid() { 12 return cid; 13 } 14 15 public void setCid(Long cid) { 16 this.cid = cid; 17 } 18 19 public String getCname() { 20 return cname; 21 } 22 23 public void setCname(String cname) { 24 this.cname = cname; 25 } 26 27 public String getDescription() { 28 return description; 29 } 30 31 public void setDescription(String description) { 32 this.description = description; 33 } 34 35 public Set<Student> getStudents() { 36 return students; 37 } 38 39 public void setStudents(Set<Student> students) { 40 this.students = students; 41 } 42 43 private Set students; 44 }
Classes.hbm.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <hibernate-mapping> 5 <class name="cn.itcast.hiberate.sh.domain.Classes"> 6 <!-- 7 缓存策略 8 --> 9 <cache usage="read-write"/><!--对这个对象开启二级缓存 对于update测试用read-write 对查询的是read-only就可以了--> 10 <id name="cid" length="5" type="java.lang.Long"> 11 <generator class="increment"></generator> 12 </id> 13 <property name="cname" length="20" type="java.lang.String"></property> 14 15 <property name="description" length="100" type="java.lang.String"></property> 16 <!-- 17 set元素对应类中的set集合 18 通过set元素使classes表与student表建立关联 19 key是通过外键的形式让两张表建立关联 20 one-to-many是通过类的形式让两个类建立关联 21 22 cascade 级联 23 save-update 24 1、当 保存班级的时候,对学生进行怎么样的操作 25 如果学生对象在数据库中没有对应的值,这个时候会执行save操作 26 如果学生对象在数据库中有对应的值,这个时候会执行update操作 27 delete 28 all 29 inverse 维护关系 30 true 不维护关系 31 false 维护关系 32 default false 33 --> 34 <set name="students" cascade="save-update" inverse="true" fetch="select"> 35 <!-- 36 key是用来描述外键 37 --> 38 <key> 39 <column name="cid"></column> 40 </key> 41 <one-to-many class="cn.itcast.hiberate.sh.domain.Student"/> 42 </set> 43 </class> 44 </hibernate-mapping>
测试
1 package cn.itcast.hibernate.sh.test; 2 3 import java.util.List; 4 import java.util.Set; 5 6 import org.hibernate.Session; 7 import org.hibernate.Transaction; 8 import org.junit.Test; 9 10 import cn.itcast.hiberate.sh.domain.Classes; 11 import cn.itcast.hiberate.sh.domain.Student; 12 import cn.itcast.hibernate.sh.utils.HiberanteUtils; 13 14 public class SecondCacheTest extends HiberanteUtils{ 15 static{ 16 url = "hibernate.cfg.xml"; 17 } 18 19 /** 20 * session.get 21 * 把数据存在一级缓存和二级缓存 22 */ 23 @Test 24 public void testGet(){ 25 Session session = sessionFactory.openSession(); 26 Classes classes = (Classes)session.get(Classes.class, 1L); //放入一级缓存 并且放入二级缓存 27 session.close(); //关闭了一级缓存了 28 session = sessionFactory.openSession(); 29 classes = (Classes)session.get(Classes.class, 1L); //这个时候不发出查询语句,因为从二级缓存中查询了 30 session.close(); 31 } 32 33 /** 34 * session.load 35 * 同上 36 */ 37 @Test 38 public void testLoad(){ //与get方法的情况是一样的 39 Session session = sessionFactory.openSession(); 40 Classes classes = (Classes)session.load(Classes.class, 1L); 41 classes.getCname(); 42 session.close(); 43 session = sessionFactory.openSession(); 44 classes = (Classes)session.load(Classes.class, 1L); 45 classes.getCname(); 46 session.close(); 47 } 48 49 /** 50 * session.update 51 */ 52 @Test 53 public void testUpdate(){ 54 Session session = sessionFactory.openSession(); 55 //session.beginTransaction(); 56 Classes classes = new Classes(); 57 classes.setCid(1L); 58 classes.setCname("aaa"); 59 session.update(classes); 60 61 session.close(); 62 session = sessionFactory.openSession(); 63 classes = (Classes)session.get(Classes.class, 1L); 64 session.close(); 65 } 66 }
查询缓存的测试
1 package cn.itcast.hibernate.sh.test; 2 3 import java.util.List; 4 import java.util.Set; 5 6 import org.hibernate.Query; 7 import org.hibernate.Session; 8 import org.hibernate.Transaction; 9 import org.junit.Test; 10 11 import cn.itcast.hiberate.sh.domain.Classes; 12 import cn.itcast.hiberate.sh.domain.Student; 13 import cn.itcast.hibernate.sh.utils.HiberanteUtils; 14 15 public class QueryCacheTest extends HiberanteUtils{ 16 static{ 17 url = "hibernate.cfg.xml"; 18 } 19 20 @Test 21 public void testQuery(){ 22 Session session = sessionFactory.openSession(); 23 Query query = session.createQuery("from Classes"); 24 query.setCacheable(true);//classes里的所有的数据要往查询缓存中存放了 打开 25 List<Classes> classesList = query.list(); 26 query = session.createQuery("from Classes"); 27 query.setCacheable(true); //打开查询缓存获取数据 28 classesList = query.list(); 29 session.close(); 30 } 31 }