这里有新鲜出炉的 Hibernate 教程,程序狗速度看过来!
Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在 Servlet/JSP 的 web 应用中使用,最具革命意义的是,Hibernate 可以在应用 EJB 的 J2EE 架构中取代 CMP,完成数据持久化的重任。
本篇文章中主要介绍了 java 中 hibernate 二级缓存详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
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 开启二级缓存
- <property name="hibernate.cache.use_second_level_cache">true</property>
3 要指定缓存的供应商
- <property name="hibernate.cache.provider_class">
- org.hibernate.cache.EhCacheProvider</property>
4 指定使用二级缓存的类
方法一 在使用类的 *.hbm.xml 配置
选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, <class> 元素的 cache 子元素表明 Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 <set> 元素中加入 <cache> 子元素
方法二 在 hibernate.cfg.xml 文件中配置 (建议)
- <!-- 指定使用二级缓存的类 放在maping下面 -->
- <!-- 配置类级别的二级缓存 -->
- <class-cache class="com.sihai.c3p0.Customer" usage="read-write"/>
- <class-cache class="com.sihai.c3p0.Order" usage="read-write"/>
- <!-- 配置集合级别的二级缓存 -->
- <collection-cache collection="com.sihai.c3p0.Customer.orders"
- usage="read-write"/>
5 配置 ehcache 默认的配置文件 ehcache.xml(名字固定)(放在类路径下)
- <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
- <diskStore path="c:/ehcache"/>
- <defaultCache
- maxElementsInMemory="5"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="true"
- maxElementsOnDisk="10000000"
- diskPersistent="false"
- diskExpiryThreadIntervalSeconds="120"
- memoryStoreEvictionPolicy="LRU"
- />
- </ehcache>
四、 测试
- 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 < Order > list = session.createQuery("from Order").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 < Customer > iterator = session.createQuery("from Customer").iterate();
- while (iterator.hasNext()) {
- Customer customer = iterator.next();
- System.out.println(customer);
- }
- 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 < Customer > list = session.createQuery("from Customer").list();
- for (Customer customer: list) {
- System.out.println(customer.getCname());
- }
- tx.commit();
- 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();
- }
- }
来源: http://www.phperz.com/article/17/1228/357149.html