Hibernate的session详解

Posted crazylover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate的session详解相关的知识,希望对你有一定的参考价值。

一、hibernate的session介绍

Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应。Session 能够在某些时间点, 按照缓存中对象的变化来执行相关的 SQL 语句, 来同步更新数据库, 这一过程被称为刷新缓存(flush)。也叫一级缓存。
在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存。 只要 Session 实例没有结束生命周期, 且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。Session 缓存可减少 Hibernate 应用程序访问数据库的频率。

 session缓存的示例:

    @Test
    public void getUser(){
        User user=session.get(User.class,1);
        User user2=session.get(User.class,1);
        System.out.println(user);
        System.out.println(user2);//查询出来的两条记录完全一样
    }

技术分享图片

 

二、session缓存的操作方法:

  技术分享图片

(1)flush方法:session会按照缓存中对象属性的变化来更新数据库中的记录,使数据库中记录和缓存中的对象保持一致,默认情况下,在以下时间点会刷新缓存:

  ①:当应用程序调用Transaction.commit()方法时,该方法会先调用flush()方法,然后提交事物

  ②:显示的调用flush()方法时

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

flush 缓存的例外情况:

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

  hibernate的主键生成策略:

  技术分享图片

flush()和commit()方法的区别:

  flush()方法会执行一系列的sql语句,但是不会提交事物;commit()在提交事物前,会先调用flush()方法,然后i在提交事物,提交事物以为这将数据库的操作永久的保存下来

(2)refresh:

  refresh会强制发送select语句, 以使数据库中的记录和缓存中的对象保持一致;如果在调用refresh方法前,手动的修改数据库中的记录,查询出来的结果还不是最新的,这跟数据库的数据的隔离级别是相关的,可以在配置文件中显示的修改事物的隔离级别,每一个隔离级别都对应一个整数;

<property name="hibernate.connection.isolation">2</property>

Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED ,mysql支持四中事物的隔离级别:

  1. READ UNCOMMITED
  2. READ COMMITED
  4. REPEATABLE READ
  8. SERIALIZEABLE

(3)clear 清理缓存

三、持久化对象的状态

  持久化对象状态分为四种状态:持久化状态, 临时状态, 游离状态, 删除状态。Session 的特定方法能使对象从一个状态转换到另一个状态;

技术分享图片

(1)update方法:

  ①:若更新一个持久化对象,不必显示的调用update()方法,因为在嗲用Transaction的commit()方法时,会调用session的flush()

  ②:更新一个游离对象,需要显示的调用update()方法,可以将一个游离对象转换为持久化对象

  ③:当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常

  ④:当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常.

    @Test
    public void testUpdate(){
        User user=session.get(User.class,1);
        transaction.commit();
        session.close();
        session=sessionFactory.openSession();
        transaction=session.beginTransaction();
        user.setUserName("James");//会发送update()语句
        //但是如果不修改user的任何属性,也会发送update语句,如何避免盲目的发送sql?
        // 可以通过在hbm.xml文件的class标签中加入select-before-update="true" ,默认为false
        session.update(user);
    }

 (2)saveOrUpdate:

  如果user是临时对象,则调用save()方法,如果user是游离对象,则调用update()方法

  判断对象是不是临时对象:

    ①:Java 对象的 OID 为 null

    ②:映射文件中为 <id> 设置了 unsaved-value 属性, 并且 Java 对象的 OID 取值与这个 unsaved-value 属性值匹配

(3)delete

  删除操作,如果OID和数据库中的一条记录保持一致,则执行删除操作,,把对象从 Session 缓存中删除, 该对象进入删除状态,若OID在数据库中没有对应的记录,则抛出异常,Hibernate 的 cfg.xml 配置文件中有一个 hibernate.use_identifier_rollback 属性, 其默认值为 false, 若把它设为 true, 将改变 delete() 方法的运行行为: delete() 方法会把持久化对象或游离对象的 OID 设置为 null, 使它们变为临时对象

  






以上是关于Hibernate的session详解的主要内容,如果未能解决你的问题,请参考以下文章

hibernate_03_session详解

hibernate课程 初探单表映射2-6 session详解(下)

Hibernate详解

Hibernate中一级缓存和二级缓存使用详解

session详解

08-session详解