java中hibernate二级缓存详解

网友投稿 229 2023-05-18


java中hibernate二级缓存详解

Hibernate的二级缓存

一、缓存概述

缓存(Cache): 计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存

hibernate中提供了两个级别的缓存

第一级别的缓存是 Session 级别的缓存,它是属于事务范围的缓存。这一级别的缓存由 hibernate 管理的,一般情况下无需进行干预

第二级别的缓存是 SessionFactory 级别的缓存,它是属于进程范围的缓存

Hibernate 的缓存可以分为两类:

内置缓存: Hibernate 自带的, 不可卸载. 通常在 Hibernate 的初始化阶段, Hibernate 会把映射元数据和预定义的 SQL 语句放到 SessionFactory 的缓存中, 映射元数据是映射文件中数据的复制, yKJxjjX而预定义 SQL 语句时 Hibernate 根据映射元数据推到出来的. 该内置缓存是只读的.

外置缓存(二级缓存): 一个可配置的缓存插件. 在默认情况下, SessionFactory 不会启用这个缓存插件. 外置缓存中的数据是数据库数据的复制, 外置缓存的物理介质可以是内存或硬盘

二、理解二级缓存的并发访问策略

三、配置进程范围内的二级缓存(配置ehcache缓存)

1 拷贝ehcache-1.5.0.jar到当前工程的lib目录下

依赖 backport-util-concurrent 和 commons-logging

2 开启二级缓存

true

3 要指定缓存的供应商

org.hibernate.cache.EhCacheProvider

4 指定使用二级缓存的类

方法一 在使用类的*.hbm.xml配置

选择需要使用二级缓存的持久化类, 设置它的二级缓存的并发访问策略, 元素的 cache 子元素表明 Hibernate 会缓存对象的简单属性, 但不会缓存集合属性, 若希望缓存集合属性中的元素, 必须在 元素中加入 子元素

方法二  在hibernate.cfg.xml文件中配置(建议)

usage="read-write"/>

5  配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)

maxElementsInMemory="5"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

maxElementsOnDisk="10000000"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU"

/>

四、 测试

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

}

}

usage="read-write"/>

5  配置ehcache默认的配置文件ehcache.xml(名字固定)(放在类路径下)

maxElementsInMemory="5"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

maxElementsOnDisk="10000000"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU"

/>

四、 测试

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

}

}

maxElementsInMemory="5"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

maxElementsOnDisk="10000000"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU"

/>

四、 测试

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

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java通过 Socket 实现 TCP服务端
下一篇:spring boot 的常用注解使用小结
相关文章

 发表评论

暂时没有评论,来抢沙发吧~