Hibernate_Session 缓存(Hibernate 一级缓存)

在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存. 只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期

Session 缓存可减少 Hibernate 应用程序访问数据库的频率。

News news = (News) session.get(News.class, 1);
System.out.println(news);
News news2 = (News) session.get(News.class, 1);
System.out.println(news2);

以上语句只会发送一条sql语句

flush:Session 按照缓存中对象的属性变化来同步更新数据库

默认情况下 Session 在以下时间点刷新缓存:

显式调用 Session 的 flush() 方法

当应用程序调用 Transaction 的 commit()方法的时, 该方法先 flush ,然后在向数据库提交事务

当应用程序执行一些查询(HQL, Criteria)操作时,如果缓存中持久化对象的属性已经发生了变化,会先 flush 缓存,以保证查询结果能够反映持久化对象的最新状态

flush 缓存的例外情况: 如果对象使用 native 生成器生成 OID, 那么当调用 Session 的 save() 方法保存对象时, 会立即执行向数据库插入该实体的 insert 语句.

commit() 和 flush() 方法的区别:flush 执行一系列 sql 语句,但不提交事务;commit 方法先调用flush() 方法,然后提交事务. 意味着提交事务意味着对数据库操作永久保存下来。

/**
     * flush: 使数据表中的记录和 Session 缓存中的对象的状态保持一致. 为了保持一致, 则可能会发送对应的 SQL 语句.
     * 1. 在 Transaction 的 commit() 方法中: 先调用 session 的 flush 方法, 再提交事务
     * 2. flush() 方法会可能会发送 SQL 语句, 但不会提交事务. 
     * 3. 注意: 在未提交事务或显式的调用 session.flush() 方法之前, 也有可能会进行 flush() 操作.
     * 1). 执行 HQL 或 QBC 查询, 会先进行 flush() 操作, 以得到数据表的最新的记录
     * 2). 若记录的 ID 是由底层数据库使用自增的方式生成的, 则在调用 save() 方法时, 就会立即发送 INSERT 语句. 
     * 因为 save 方法后, 必须保证对象的 ID 是存在的!
     */
    @Test
    public void testSessionFlush2(){
        News news = new News("Java", "SUN", new Date());
        session.save(news);
    }
    
    @Test
    public void testSessionFlush(){
        News news = (News) session.get(News.class, 1);
        news.setAuthor("Oracle");
        
//        session.flush();
//        System.out.println("flush");
        //执行 HQL 或 QBC 查询, 会先进行 flush() 操作, 以得到数据表的最新的记录
        News news2 = (News) session.createCriteria(News.class).uniqueResult();
        System.out.println(news2);
    }
/**
     * refresh(): 会强制发送 SELECT 语句, 以使 Session 缓存中对象的状态和数据表中对应的记录保持一致!
     */
    @Test
    public void testRefresh(){
        News news = (News) session.get(News.class, 1);
        System.out.println(news);
        
        session.refresh(news); 
        System.out.println(news); 
    }

以上的refresh()要把数据库的隔离级别设置为以下才有用:

<!-- 设置 Hibernate 的事务隔离级别 -->
<property name="connection.isolation">2</property>
/**
     * clear(): 清理缓存
     */
    @Test
    public void testClear(){
        News news1 = (News) session.get(News.class, 1);
        
        session.clear();
        
        News news2 = (News) session.get(News.class, 1);
    }

以上代码会发送两条sql语句,因为clear()已经把缓存清理掉了

猜你喜欢

转载自blog.csdn.net/qq_36901488/article/details/82763986
今日推荐