hibernate12–缓存详解编程语言

<!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.url"> 
        jdbc:oracle:thin:@localhost:1521:orcl 
    </property> 
    <property name="connection.username">t10</property> 
    <property name="connection.password">t10</property> 
    <property name="connection.driver_class"> 
        oracle.jdbc.OracleDriver 
    </property> 
    <!--方言  --> 
    <property name="dialect"> 
        org.hibernate.dialect.Oracle9Dialect 
    </property> 
    <property name="show_sql">true</property> 
    <property name="hbm2ddl.auto">update</property> 
    <!-- 在我们的项目中使用currentSession--> 
    <property name="current_session_context_class">thread</property> 
    <!-- 开启配置2级缓存 --> 
    <property name="cache.use_second_level_cache">true</property> 
    <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
     <!-- 开启查询缓存 --> 
    <property name="cache.use_query_cache">true</property> 
 
 
    <!--加载我们配置的映射文件  全路径 --> 
    <mapping resource="cn/bdqn/bean/Dept.hbm.xml" /> 
    <mapping resource="cn/bdqn/bean/Emp.hbm.xml" /> 
 
</session-factory> 
</hibernate-configuration>
复制代码

 

 

<?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="cn.bdqn.bean"> 
  <class name="Emp"> 
  <!-- 配置2级缓存策略 --> 
    <cache usage="read-only"/> 
   
       <id name="empNo">  
          <generator class="assigned"/><!-- 手动给主键赋值 --> 
       </id>   
       <property name="empName"/> 
       <property name="job"/> 
       <property name="sal" column="salary"/> 
       <property name="hireDate"/> 
       <!-- 配置多对一关联 
       name:对应的是  本类中 关联关系的属性名 
       column:对应数据库中 两个表的  外键! 
       class:关联的实体类 
       --> 
       <many-to-one  name="dept" column="DEPTNO" class="Dept"/>  
  </class> 
</hibernate-mapping>

 

<ehcache> 
 
<!-- java.io.tmpdir:临时系统文件!  可以换成自己创建的目录下 --> 
    <diskStore path="java.io.tmpdir"/> 
 
 
    <!-- 
  maxElementsInMemory:在内存中 最大的存储量  10000对象 
  eternal:是否永远不销毁 
  timeToIdleSeconds:当前缓存的数据闲置多少时间被销毁  以秒为单位 
  timeToLiveSeconds:当前缓存的数据超过多少时间被销毁 以秒为单位 
  overflowToDisk: 是否写入磁盘 
  diskPersistent:硬盘文件是否永久保存 
  memoryStoreEvictionPolicy:  缓存清理策略: 
 
         FIFO ,first in first out (先进先出). 
          
        LFU , Less Frequently Used (最少使用). 
        意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。 
         
        LRU ,Least Recently Used(最近最少使用).  
        (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了, 
        而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 
    --> 
    <defaultCache 
            maxElementsInMemory="10000" 
            eternal="false" 
            timeToIdleSeconds="120" 
            timeToLiveSeconds="120" 
            overflowToDisk="true" 
            memoryStoreEvictionPolicy="LRU" 
            /> 
</ehcache>

 

 

package cn.bdqn.test; 
import java.util.ArrayList; 
import java.util.List; 
import oracle.net.aso.s; 
import org.hibernate.CacheMode; 
import org.hibernate.Criteria; 
import org.hibernate.Query; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.criterion.DetachedCriteria; 
import org.hibernate.criterion.MatchMode; 
import org.hibernate.criterion.Order; 
import org.hibernate.criterion.Projections; 
import org.hibernate.criterion.Property; 
import org.hibernate.criterion.Restrictions; 
import org.hibernate.transform.Transformers; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
import com.sun.org.apache.xml.internal.security.encryption.Transforms; 
import cn.bdqn.bean.Dept; 
import cn.bdqn.bean.Emp; 
import cn.bdqn.util.HibernateUtil; 
public class EmpTest { 
/** 
* 1级缓存:  session中的缓存 
*  clear():清空session中所有的缓存对象 
*  evict():清除session中指定的对象 
*/ 
@Test 
public   void  test01(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql 
session.clear();  //清空缓存 
emp = (Emp) session.get(Emp.class, 1);  //产生1条sql 
} 
@Test 
public   void  test02(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp = (Emp) session.load(Emp.class, 1);  
session.clear();  //清空缓存 
emp = (Emp) session.load(Emp.class, 1);   
} 
@Test 
public   void  test03(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp1 = (Emp) session.get(Emp.class, 1); //产生1条sql 
Emp emp2 = (Emp) session.get(Emp.class, 2); //产生1条sql 
session.evict(emp1);  //清除指定的 
} 
@Test 
public   void  test04(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp=new Emp(); 
emp.setEmpNo(51); 
emp.setEmpName("haha"); 
session.save(emp); 
session.evict(emp);  //清除指定的 
transaction.commit(); // 能保存到数据库中吗? 肯定不能保存  除非把 session.evict(emp); 去掉 
} 
@Test 
public   void  test05(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp=new Emp(); 
emp.setEmpNo(52); 
emp.setEmpName("haha"); 
session.save(emp);  //持久态 
System.out.println("********"); 
session.flush();   //产生sql语句  把 emp对象 同步到 数据库 
System.out.println("********"); 
session.evict(emp);  //清除指定的   但是 已经  清理了 缓存 
transaction.commit(); // 能保存到数据库中,因为已经flush 
} 
@Test 
public   void  test06(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp=(Emp) session.get(Emp.class, 1);  //持久化 
emp.setEmpName("haha");   //emp 脏对象 
System.out.println("flush前******************"); 
session.flush();  //同步数据库 
System.out.println("flush后******************"); 
emp=(Emp) session.get(Emp.class, 1);  //持久化 
System.out.println(emp.getEmpName());  //输出 haha   证明同步到数据库中了 
emp.setEmpName("heihei");   //emp 脏对象 
transaction.commit(); 
}     
/** 
* 2级缓存:  进程或者是集群范围内的缓存!是sessionFactory的缓存! 
* 一个sessionFactory可以创建N个session! 
* 也就是说 在2级缓存中的数据,N个session共享! 
*  
*  
* 2级缓存适合存放的数据: 
* 01.不经常被修改的数据 
* 02.不敏感的数据  (财务数据不能放入) 
* 03.共享的数据   
*  
*  
* 配置ehCache缓存 
* 01.引入jar 
* 02.找到对应xml文件 
* 03.在hibernate.cfg.xml文件中  开启和配置缓存 
* 04.在对应的映射文件中  配置  缓存的策略 
*/ 
@Test 
public   void  test07(){  //之前是 两条sql语句 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql 
session.clear();  //清空缓存 
emp = (Emp) session.get(Emp.class, 1);  
} 
/** 
* 验证我们  映射文件中的    <cache usage="read-only"/> 
*/ 
@Test 
public   void  test08(){   
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql 
emp.setEmpName("hahaahaha"); 
session.update(emp); 
transaction.commit();  //报错   can't  writer  to readonly  object!! 
} 
//java.io.tmpdir:临时系统文件!  可以换成自己创建的目录下 
@Test 
public  void  test09(){ 
System.out.println(System.getProperty("java.io.tmpdir")); 
} 
/** 
* 设置2级缓存 模式 
* CacheMode.IGNORE: 不与2级缓存关联                                产生2条sql 
* CacheMode.NORMAL:与2级缓存关联,可读可写                   产生1条sql 
* CacheMode.GET:与2级缓存关联,只读                                  产生1条sql 
* CacheMode.PUT:与2级缓存关联,只写                                  产生2条sql 
* CacheMode.REFRESH:与2级缓存关联,只写   
* 通过 hibernate.cache.use_minimal_puts 的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。 
*                     产生2条sql 
*/ 
@Test 
public  void  test10(){ 
Session session = HibernateUtil.getCurrentSession(); 
Transaction transaction = session.beginTransaction(); 
Emp emp = (Emp) session.get(Emp.class, 1); // 产生1条sql 
session.clear(); 
//设置缓存模式 
session.setCacheMode(CacheMode.REFRESH); 
emp = (Emp) session.get(Emp.class, 1);  
} 
/* 
* 查询缓存 
*   基于2级缓存!   
*   第一次在网页中查询一个关键字 为 java的所有 页面 可能需要等待 2S 
*   第2次在网页中查询一个关键字 为 java的所有 页面   必须 小于2S 
*    
*   01.去核心配置文件中配置 
*   <property name="cache.use_query_cache">true</property> 
*   02.手动开启查询缓存 
*   query.setCacheable(true); 
*/ 
@Test 
public void test11(){ 
Session session = HibernateUtil.getCurrentSession(); 
Query query = session.createQuery("from Dept"); 
query.setCacheable(true); //首次开启 ! 之后如果还是这个query语句,那么就会启动查询缓存 
List list = query.list(); 
for (Object object : list) { 
System.out.println(object); 
} 
System.out.println("****************************"); 
Query query2 = session.createQuery("from Dept"); 
query2.setCacheable(true);  //先去 查询缓存中查找 
List list2 = query2.list(); 
for (Object object : list2) { 
System.out.println(object); 
} 
System.out.println("****************************"); 
Query query3 = session.createQuery("from Dept"); 
//query3.setCacheable(true); 
List list3 = query3.list(); 
for (Object object : list3) { 
System.out.println(object); 
} 
session.close(); 
} 
}

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/12108.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论