kristain

博客园 首页 新随笔 联系 订阅 管理

  

  Session具有一个缓存,是一块内存空间,在这个内存空间存放了相互关联的java对象,这种位于Session缓存内的对象也被称为持久化对象,Session是负责根据持久化对象的状态变化来同步更新数据库的。

  Session的缓存是内置的,不能被卸除的,也被称为Hibernate的第一级缓存。在正常情况下一级缓存是由Hibernate自动维护的,无需人工干预。

(一)理解一级缓存

  • 当应用程序调用Session接口的save()、update()、saveOrUpdate时,如果Session缓存中还不存在相应的对象,Hibernate就会自动的把该对象加入到一级缓存中去。
  • 当调用Session接口的load()、get()以及Query查询接口的list(),iterator()方法时,如果Session缓存中存在相应的对象,则不需要到数据库中去检索。
  • 当调用Session的close()方法时,Session缓存就被清空。

(二)Session接口的用法

  Session接口是Hibernate向应用程序提供操纵数据库的最主要的接口,它提供了基本的保存、更新、删除和加载等方法。

Java对象在Hibernate持久化层的状态

  • 临时状态(transient):刚用new语句创建,还没被持久化,数据库中也没有与之对应的记录,并且不处于session缓存中。(处于临界状态的对象称为临时对象)
  •  
  • 持久化状态(persistent):已经被持久化,并且加入到Session缓存中。(处于持久化状态的对象称为持久化对象)
  • 删除状态:不再处于Session缓存中,并且Session已经计划将其从数据库中删除。
  • 游离状态(detached):已经被持久化,但不再处于Session缓存中。(处于游离状态的对象称为游离对象)

  当通过load()和get()方法得到的pojo对象,它们都处于persistent状态,但如果执行delete()方法时(不执行事务),该pojo对象状态就处于detached,(表示和Session脱离关联),因delete()而变成游离状态可以通过sava()或saveOrUpdate()变成持久态。

  当Session关闭时,Session缓存中的persistent的pojo对象也变成detached,因关闭Session而变成游离态可以通过lock()、save()、update()变成持久态。持久态实例可以通过调用delete()变成detached态。

  通过get()和load()获得的pojo实例都是持久化状态的。detached态的实例可以通过调用lock()或replicate()进行持久化。

  save()和persist()将会引发SQL的Insert,delete()会引发SQL的Delete,而update()或merge()会引发SQL的Update。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQL的Update。saveOrUpdate()或replicate()会引发SQL Insert或Update。

  更简单的说,get()、load()和delete()操纵的是存在Session缓存中的pojo对象,save()、persist()、lock()、update()、merge()和replicate()操纵的是不在Session缓存中的pojo对象,其意是持久化数据的同时重新把pojo对象加入缓存。


update()、saveOrUpdate()和merge() 

  如果pojo对象已经在本Session中持久化了,在本Session中执行saveOrUpdate不做任何事。

  saveOrUpdate如果对象没有持久化标识(identifier)属性,对其调用save(),否则调用update()。

  如果Session中存在相同持久化标识的实例,用用户给出的对象覆盖Session已有的持久化实例,如果使用update,执行完后,会抛出异常,但当我们使用merge方法的时候,把处理自由态(transient)的pojo对象A的属性copy到持久态的pojo对象B的属性中,执行完成后原来是持久状态的B还是持久状态,而我们提供的A还是自由态。


sava()和persist()

  save()方法把一个临时对象加入到Session缓存中,并持久化该临时对象,计划执行一个insert语句。

  persist()和save()方法类似,也能把一个临时对象转变为持久化对象。

区别:

  ·persist()是在Hibernate3版本中才出现。在使用代理主键的情况下persist()方法不保证立即为持久化对象的ID赋值,而是有可能在Session清理缓存时才为ID赋值。(不保证标识符被立即填入持久化实例中,标识符的填入可能被推迟到flush的时候)

  ·如果在事务边界以外调用persist()方法,那么该方法不会计划执行insert语句,这可以提高负责长时间运行事务的程序的健壮性。而save()方法,不管是在事务边界以外或内调用它,都会执行insert语句。

  注:代理主键是指与业务无关且能唯一标识数据库中记录,一般是数据库自动生成的,比如mysql可以使用auto_increment,Sql2000可以使用identity生成方式,oracle可以使用sequence生成方式;自然主键指业务相关,由用户指定,且能唯一标识数据库中的任意一条记录。

    事务边界:为了给自己的事务定界,可以使用关键字BEGIN TRANSACTION和ROLLBACK TRANSACTION或COMMIT TRANSACTION。


flush()和update()

  update操作是在自由态或游离状态(因Session关闭而处于游离状态)的对象,而flush是操作在持久状态的对象。

  

  

  

posted on 2011-05-07 20:04  kristain  阅读(3032)  评论(0编辑  收藏  举报