`

【转】Hibernate-Session

阅读更多

当讨论Hibernate的Session时,都是在讨论它做为Hibernate的一级缓存出现,当然这是它的功能,但也仅仅是它提供的功能之一,而且是一个附带功能, 就像Class.forName(),它的功能是加载一个类型并将此类型的Class对象返回,可是更多的时候我们都忽略了它的返回值,只知使用它会引起类加载的功能.现在你还记得Session的功能除了做为Hibernate的一级缓存之外的其它功能吗...
它所提供的功能要从它所解决的问题入手,我们先来看一下它所关注的问题。问题就是数据存取当中的行为问题。行为问题指的是如何让各种对象从数据库中读取出来以及保存到数据库中。在这一过程中需要注意的问题。

 

  1. 首先的一个问题就是并发问题,当你从数据库中读取一条数据出来,可是就在此时,其它人也读取了这条数据,如果都是仅仅读取,那问题不大,但如果都修改呢,同时修改共享资源,并发问题就出现了,这就需要要保证这一过程是在一个事务范围内。
  2. 从数据库中加载记录,在这一操作范围内需要保证只有一个对象和数据库中的这条记录相对应,应该将其理解为:从数据库中加载记录到一个对象的这个操作过程其实是从数据库到应用程序内的延伸,虽然执行位置换了,但它们都要做出一致的承诺。
  3. 读取出一个对象后你很可能希望修改下对象的状态,这时要跟踪对象的状态变化,生成相应的sql语句。
  4. 对于新建行的的id重新获取。
  5. 对象与对象是有依赖关系的,对象之间很容易表达双向关联,但数据库只能表达单向关联。双向关联的对象应该根据其中一方的状态生成sql语句,避免无谓的sql语句。查询对象时,因为是关联的,会连带查询出很多对象,有些是不必要的,应使用延迟加载来防止程序不会使用到的对象被查询出来。
  6. 按排sql语句的执行顺序,insert、update、delete的先后顺序,及级联操作时的行为。保证插入时首先插入主表数据,其次是从表数据,删除时首先删除从表数据,其次是主表数据。还包括其它更丰富的的级联更新行为。 

Session都很好的解决上面的六点问题。
session中对象的标识符和数据库中的主键相对应,Session会在其内部维护一个哈希表,当从数据库查询出一条记录,它会首先检查哈希表中是否有之条记录相应的对象。存在所查对象就直接从哈希表中取出, 不存在相应对象就把当前查出的对象添加到哈希表中,并返回此对象。

 

Session如何判断对象的状态是否发生了改变呢?它用一种快照的方式。就是当查询出一条记录后,会在内存中生成一个相应的的对象,然后保留这个对象的一个拷贝,当对象状态改变后,Session根据变化后的状态和留有的对象拷贝进行快照对比,以生成相应的sql语句。当事务提交之前,Session整理这一组sql语句,按照正确的顺序作为一个批处理进行执行。在跟踪对象状态时,需要将当前对象缓存。但一定要记住,进行缓存的主要目的在于保持与数据库的一致性,而不是提高性能。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics