hibernate优化策略02一级缓存和快照

一、什么是Hibernate的一级缓存

session将一个对象加入自己的管理范围内,其实也就是把该对象放入自己的一级缓存中。
Hibernate的一级缓存是指Session级别的缓存, 它是一块内存空间,由Hibernate管理,无需干预。 有了一级缓存,应用程序可以减少访问数据库的次数,提高性能。

查询时:首先会使用对象属性的OID值(对应表中的主键)在Hibernate的一级缓存进行查找:
如果找到,则取出返回,不会再查询数据库,
如果没有找到,再到数据库中进行查询操作。然后将查询结果存放到Session一级缓存中。

保存时:例如,session.save(customer);这个语句就是将 customer保存在自己的一级缓存中,等待事务提交后,hibernate才真正的发sql语句,对数据库进行操作。注意:session进行操作的时候,是将对象加入自己的一级缓存,并不是就直接跟数据库打交道了。

测试一级缓存
测试查询时的一级缓存:只执行一次sql语句
public class CacheLevelOneTest {
    
    @Test
    public void testCache(){

        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        //第1次查询
        Customer c1 = session.get(Customer.class, 1L);
        System.out.println(c1);

        //第2次查询
        Customer c2 = session.get(Customer.class,1L);
        System.out.println(c2);

        tx.commit();
        session.close();
    }
}



二、Hibernate 的快照机制

这里引用一个文章https://www.cnblogs.com/hlhdidi/p/6139020.html

在一级缓存中会做些什么事情呢?为什么能够知道是发insert、还是update呢?那这里就要提到一个快照的概念了。

1、快照是数据的副本 

2、快照的作用:保证数据一致性

Q:为什么持久态对象可以影响数据库?
A:因为 Hibernate 的 Session 内部存在一级缓存和快照机制!


三、一级缓存的管理

1、一级缓存的自动清空
session.close()
以下例子在第三次查询之前关闭了session,因此一级缓存被清空,所以需要重新执行sql语句
@Test
public void testCache(){

    Session session = HibernateUtil.openSession();
    Transaction transaction = session.beginTransaction();

    //查询
    Customer customer1 = session.get(Customer.class, 4L);
    System.out.println("第一次查询:" + customer1.getName());

    Customer customer2 = session.get(Customer.class, 4L);
    System.out.println("第二次查询:" + customer2.getName());

    transaction.commit();//存入数据库
    session.close();


    session = HibernateUtil.openSession();
    transaction = session.beginTransaction();

    Customer customer3 = session.get(Customer.class, 4L);
    System.out.println("第三次查询:" + customer2.getName());

    transaction.commit();//存入数据库
    session.close();
}

2、把对象移出一级缓存的方法:
session.evict(object) : 把一个对象移出一级缓存
session.clear() : 把一级缓存的所有对象移出

复制前面的 testPersistentStatus方法,并作修改
以下测试数据不会被更新:
/**
 * 测试清空一级缓存
 */
@Test
public void testClearCacheLevelOne(){

    Session session = HibernateUtil.openSession();
    Transaction tx = session.beginTransaction();

    //获取到一个持久态对象
    Customer customer = new Customer();
    customer.setName("老王");
    session.save(customer);

    //修改customer的数据
    customer.setName("汤姆1");

    //把customer对象移出一级缓存
    session.evict(customer);
    //清空一级缓存
    //session.clear();

    tx.commit();//事务提交时自动执行update方法
    session.close();
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值