Hibernate的二级缓存
一、缓存概述
缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存
hibernate中提供了两个级别的缓存
第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预
第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存
Hibernate 的缓存可以分为两类:
内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, 而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.
外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘
二、理解二级缓存的并发访问策略
三、配置进程范围内的二级缓存(配置ehcache缓存)
1 拷贝ehcache-1.5.0.jar到当前工程的lib目录下
依赖 backport-util-concurrent 和 commons-logging
2 开启二级缓存
3 要指定缓存的供应商
4 指定使用二级缓存的类
方法一 在使用类的*.hbm.xml配置
选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略,
四、 测试
package com.sihai.hibernate3.test;
import java.util.Iterator;import java.util.List;
import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;
import com.sihai.hibernate3.demo1.Customer;import com.sihai.hibernate3.demo1.Order;import com.sihai.utils.HibernateUtils;
public class HibernateTest6 {
@Test// 查询缓存的测试public void demo9(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Query query = session.createQuery("select c.cname from Customer c");// 使用查询缓存:query.setCacheable(true);query.list();
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
query = session.createQuery("select c.cname from Customer c");query.setCacheable(true);query.list();
tx.commit();}
@SuppressWarnings("unused")@Test// 更新时间戳public void demo8(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 2);session.createQuery("update Customer set cname = '奶茶' where cid = 2").executeUpdate();
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 2);
tx.commit();}
@SuppressWarnings("all")@Test// 将内存中的数据写到硬盘public void demo7(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
List
tx.commit();}
@Test// 一级缓存的更新会同步到二级缓存:public void demo6(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1);customer.setCname("芙蓉");
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
tx.commit();}
@SuppressWarnings("unchecked")@Test// iterate()方法可以查询所有信息.
// iterate方法会发送N+1条SQL查询.但是会使用二级缓存的数据public void demo5(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
// N+1条SQL去查询.
Iterator
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
iterator = session.createQuery("from Customer").iterate();while(iterator.hasNext()){Customer customer = iterator.next();System.out.println(customer);}
tx.commit();}
@SuppressWarnings("unchecked")@Test// 查询所有.Query接口的list()方法.
// list()方法会向二级缓存中放数据,但是不会使用二级缓存中的数据.
public void demo4(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
// 查询所有客户:// list方法会向二级缓存中放入数据的.
List
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
// Customer customer = (Customer) session.get(Customer.class, 1);// 没有发生SQL ,从二级缓存获取的数据.
// list()方法没有使用二级缓存的数据.
list = session.createQuery("from Customer").list();for (Customer customer : list) {System.out.println(customer.getCname());}
tx.commit();}
@Test// 二级缓存的集合缓冲区特点:public void demo3(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1);// 查询客户的订单.
System.out.println("订单的数量:"+customer.getOrders().size());
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);// 查询客户的订单.
System.out.println("订单的数量:"+customer2.getOrders().size());
tx.commit();}
@SuppressWarnings("unused")@Test// 配置二级缓存的情况public void demo2(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL.
Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
System.out.println(customer1 == customer2);
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
Customer customer3 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
Customer customer4 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
System.out.println(customer3 == customer4);
tx.commit();}
@SuppressWarnings("unused")@Test// 没有配置二级缓存的情况public void demo1(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);// 发送SQL.
Customer customer2 = (Customer) session.get(Customer.class, 1);// 不发送SQL.
tx.commit();
session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();
Customer customer3 = (Customer) session.get(Customer.class, 1);// 发送SQL.
tx.commit();}}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:详解Java的Hibernate框架中的缓存与二级缓存详解Java的Hibernate框架中的缓存与原生SQL语句的使用详解Java的Hibernate框架中的注解与缓存浅析Java的Hibernate框架中的缓存和延迟加载机制java模拟hibernate一级缓存示例分享java中Hibernate缓存形式总结
