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();

    }
 }
时间: 2024-10-04 13:08:21

hibernate12--缓存的相关文章

Apache Ignite——新一代数据库缓存系统

Apache Ignite是一个通用的数据库缓存系统,它不仅支持所有的底层数据库系统,比如RDBMS.NoSQL和HDFS,还支持Write-Through和Read-Through.Write-Behind Caching等可选功能. Apache Ignite是一个聚焦分布式内存计算的开源项目,它在内存中储存数据,并分布在多个节点上以提供快速数据访问.此外,可选地将数据同步到缓存层同样是一大优势.最后,可以支持任何底层数据库存储同样让 Ignite成为数据库缓存的首先.

数据字典实现缓存

数据字典的好处很多比如: 1.可以减少使用表,来专门记录类型. 2.类型使用key检索,或者报表统计分析,在一定程度上相比汉字来讲,效率好得多. 3.使用缓存的数据字典.也可以减少不少的io操作. 等等.... 首先,库表设计就智者见智了.不多说.爱怎么设计就怎么设计. 完整的数据字典设计 ,需要 1.生成select 自定义标签. 2.list页面,或者get页面, 一个key转 value的标签 使用自定义标签,搭配上缓存的数据字典是最方便.最完美的解决办法, 接下来,就直接贴代码了. 一.

4.缓存控制技术

动态网站的数据都是从数据库获取而来的.所以网站的瓶颈往往就是反复连接数据库和大量的SQL语句查询的执行.由于HTTP协议是无状态性的,所以每次对页面请求都会执行相同的操作.我们可以让页面内容本身变化不大但是偶尔还是要变化的页面(例如新闻网站)缓存起来作为静态的页面,下一次再访问的时候直接访问静态的HTML页面即可. ① Smarty里面控制缓存 需要做3步工作:开启缓存,指定缓存目录,定义缓存的生命周期

Shiro缓存(十三)

使用缓存,可以解决每次访问请求都查数据库的问题.第一次授权后存入缓存. 缓存流程 shiro中提供了对认证信息和授权信息的缓存.shiro默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的.主要研究授权信息缓存,因为授权的数据量大. 用户认证通过. 该 用户第一次授权:调用realm查询数据库 该 用户第二次授权:不调用realm查询数据库,直接从缓存中取出授权信息(权限标识符). -------------------------------------使用ehcache缓存框架

Hibernate session缓存

一级缓存(执行代码时查看console台上的sql语句)  清空缓存 @Test public void demo03(){ //清空缓存 Session session=factory.openSession(); session.beginTransaction(); //1.查询 User user = (User)session.get(User.class, 1); System.out.println(user); //session.evitc(user) //将执行对象从一级缓存

nginx三 之缓存模块

友情提示: 缓存模块是在动静分离的环境基础上搭建,动静分离可以参考http://www.cnblogs.com/dahuandan/p/6759212.html 介绍 提高网站响应速度是web应用不容忽视的目标,在之前动静分离的基础上,我们已经降低了后端服务器压力,提高了处理请求的性能,但是用户请求的静态资源是从硬盘读取,相比内存的性能还有很大的提高: Nginx自带的缓存模块可以把静态资源缓存到内存中,提高了用户请求静态资源的速度,并且nginx自带缓存模块配置简单,使用灵活,搭配第三方插件可

一个缓存容灾写的样例

背景 有时我们能够使用缓存进行容灾的处理.场景例如以下:我们当前有一个专门提供各种数据的应用DataCore,该应用开放多个RFC方法供其它应用使用.      我们平时在读写数据时,会在Cache备份一份(为平时DataCore提高响应速度.减少DB.CPU压力所用),当DB挂掉的时候.Cache还能够用来容灾.使用缓存容灾的优点是:性能足够好,坏处是缓存可比数据库成本高多了. 让我们想象得更猛烈些,当DataCore整个挂掉的时候,A.B.C.D方怎么才干安然的执行下去? 我们能够在A.B.

浏览器缓存机制浅析

非HTTP协议定义的缓存机制 浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires: Cache-control等).但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下: <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 上述代码的作用是告诉浏览器当前页面不被缓存,每

缓存与数据库的一致性思考

时隔两年,重新启动这个博客.熟悉又有点陌生,这两年我的技术方向有了很大改变,但由于一直在使用为知笔记,因此这些改变没有提现在本博客上.之所以重启这个博客,主要是因为博客是一个开放的东西,可以带来一些交流,而笔记则是个人的东西,缺少思维碰撞.闲话少叙,这就开始. 问题:怎么保持缓存与数据库一致? 要解答这个问题,我们首先来看不一致的几种情况.我将不一致分为三种情况: 1. 数据库有数据,缓存没有数据: 2. 数据库有数据,缓存也有数据,数据不相等: 3. 数据库没有数据,缓存有数据. 在讨论这三种

构建高效可申缩的结果缓存

摘自<<JAVA并发编程实战>> public interface Computable<A, V> { V comput(A arg); } import java.util.concurrent.*; /** * 构建高效可申缩的结果缓存 * <p> * author: shiruiqiang * time: 31/01/2017 23:11 **/ public class Memoizer<A, V> implements Computa