hibernate基础(三)——主键生成策略与flush缓存清理

12 篇文章 0 订阅
    在了解此文前,请首先阅读:

[hibernate基础(二)保存一个对象(http://blog.csdn.net/wangyy130/article/details/50420545)

    在使用hibernate时,我们还是很有必要将hibernate的内部实现原理来搞清楚一下的。比如,hibernate在保存一个对象时,
    它的内部实现原理是怎样的。当然要想清楚的了解这些,就必须要从它的主键生成策略出发来一步一步深入探究!

一、保存对象简单原理

在通过hibernate来保存一个对象时,要先了解它内部的原理:

1、save

此方法在执行时,会先把一个对象放在session缓存中

(当然可以宏观上先这么理解,会有意外,这个意外也是这篇博客介绍的重点)

于此同时,在缓存中还会再生成一个临时对象的缓存区,在这块临时区域中会在进行数据库操作时,与session中的对象进行对比,最后 生成sql语句。
(在session缓存区中会有一个isDatabase这个标识来标记当前数据是否已经存在数据库中)

2、commit

    默认在执行完save之后,数据其实并没有真正的到达数据库(有意外),通常在执行完commit之后,才会是真正意义上的对象保存。
    但是默认情况下,在执行commit之前,hibernate会自动先执

flush方法,此方法用来根据临时对象缓存区生成sql语句,操作数据库

    并清理session缓存区。完成真正的数据插入操作。

二、主键生成策略

    这里并不是想一一介绍主键有哪些生成策略,而是想简单的了解一下主键的生成方式都是由什么来决定的,会造成什么影响。

1、uuid

    主要是通过hibernate生成,效率较高。所以此中方式保存对象时,在执行完save后,就会为对象的主键进行赋值。
    只有在执行完commit或者显式执行flush之后才会生成sql并清理缓存,形成真正意义上的数据保存

2、native(下面就是意外)

    通过不同数据库的能力来生成主键。所以效率相对较差。
在执行完save方法之后,由于他要去数据库中生成id,所以此时会直接生成sql并清理缓存。如果你的数据库隔离级别设置为不提交读时,
在未执行完commit方法之前就可以从数据库中查到数据了。

3、assigned

    此种方式一种会涉及到

三、显式调用flush方法

    上面说了hibernate中在执行commit时,会默认先执行flush,似乎平时用不到显式调用,那么什么时候才会用到flush的显式调用呢?

1、evict方法

    此方法是用来清理session缓存区的。
    当我们在程序中调用save方法后,有时需要调用evict方法来清理session缓存区。但此时再执行commit方法时,hibernate会报线程
不安全的错误。
首先分析下原因:

正常情况下:

    save之后,执行commit时,先执行flush方法,根据临时对象区域生成sql语句,然后清理掉临时对象区域,
会返回到session中修改isDatabase标记,修改完成后再清理session缓存区。

save之后执行evict情况

    此时,刚执行完save后,就执行evict方法,会先清理session缓存,也就是说isDatabase标记已经不存在了,那么当再执行commit时,
默认先执行flush方法时,会去修改session缓存区中的isDatabase标记,此时,标记找不到,因此会报错。

解决方案

    我们可以通过在save方法执行完成之后,显式执行flush方法,此时,会先进行数据真实保存,再清理session,这样就不会再报错了。

2、assigned手动分配与业务逻辑相结合

    如果主键配置为assigned,那么在业务逻辑中如果出现需要按顺序执行insert,update,insert这三个语句时,我们发现在commit之后,
hibernate生成语句的顺序为:insert,insert,update
那么此时,就与我们的设想偏离,若想按照原来的顺序执行,此时就可以通过显式执行flush方法来先将前两个语句进行执行,再去执行最后一个语句。

总结

主键的生成与hibernate的实现原理息息相关。同时flush方法的使用也对具体的程序开发起到很重要的作用。同时了解hibernate
中具体操作的实现原理对于理解hibernate和程序开发中的优化也有很大的帮助
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值