Hibernate的持久化类编写规范、对象标识符、一级缓存与事务绑定

12 篇文章 0 订阅
5 篇文章 0 订阅

1、持久化类编写规范

首先,什么是持久化,持久化就是将数据保存到数据库中,这样数据就被“持久化”了。那么什么是持久化类?持久化类就是与数据库表建立了映射关系的Java类。

持久化类的编写规范实际上基本等同于JavaBean的编写规范,具体描述如下:

a、持久化类需要提供无参的构造方法

b、持久化的属性需要私有,对私有的属性提供get和set方法

c、持久化类的属性要尽量使用包装类型,而避免使用基本数据类型,这是因为包装类和基本数据类型的默认值不同,包装类的类型语义描述更清晰而基本数据类型不容易描述

d、持久化类要有一个唯一标识OID与表的主键对应

e、持久化尽量不要使用final修饰,这是因为Hibernate中有延迟加载的机制,这个机制中会产生代理对象,Hibernate产生代理对象使用的是字节码的增强技术完成的,其实就是产生了当前类的一个子类对象实现的。如果使用了final修饰持久化类。那么就不能产生子类,从而就不会产生代理对象,那么Hibernate的延迟加载策略(是一种优化手段)就会失效。

 

2、对象标识符

上面持久化类编写规范中的d条提及到持久化类要有一个唯一标识OID与表的主键对应,也就是说持久化类中必须要有一个属性值,这个属性值与表的主键对应。

那么什么是OID?OID的全称是Object Identifier,即对象标识符,类似与数据库中的主键,Java中的hashCode,OID是Hibernate用来区分两个对象是否为同一个对象的标识符。因此OID必须由Hibernate来维护,具体如何维护?通过XML配置或者注解的方式来进行维护。

OID的生成略策略(主键维护策略 )

先了解一下自然主键和代理主键,自然主键指的是将具有业务含义的字段作为主键,如客户对象的身份证号。而代理主键是用一个与对象属性业务含义无关的字段来做主键,如账户表中额外生成的账户顺序号,使用最多的为代理主键!

Hibernate的主键生成策略介绍如下:

主键生成策略在xml中的配置位置如下(红色字体):

<hibernate-mapping>
    <class name="com.hibernate.limeng.Customer" table="cst_customer">
        <id name="cust_id" column="cust_id">
            <generator class="native"></generator>
        </id>
        <property name="cust_name" column="cust_name"></property>
        <property name="cust_source" column="cust_industry"></property>
        <property name="cust_level" column="cust_level"></property>
        <property name="cust_address" column="cust_address"></property>
        <property name="cust_phone" column="cust_phone"></property>
    </class>
</hibernate-mapping>

生成策略表如下:

 

 主键生成策略的一般使用方式总结如下:

increment仅仅适用于基本数据类型,很少用,identity一般适用于mysql的主键,sequence一般适用于oracle的主键,native同时适用于mysql、oracle,会根据数据库不同自动选择,uuid适用于varchar主键。

3、Hibernate的一级缓存

什么是Hibernate的一级缓存?一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。Hibernate的一级缓存的作用就是减少对数据库的访问次数。

在 Session 接口的实现中包含一系列的 Java 集合, 这些 Java 集合构成了 Session 缓存。只要 Session 实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。故一级缓存也被称为是Session基本的缓存。

快照机制:

Hibernate 向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库,并更新快照;如果一致,则不执行update语句。Hibernate快照的作用就是确保一级缓存中的数据和数据库中的数据一致。这体现在,当通过查询获取到实体类对象时,如果实体类属性值发生更改,即使不执行update,当事务提交后,也会自动更新数据库。

 

持久化类对象的三种状态

a、瞬时态

瞬时态也称为临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联

b、持久态

 持久态的对象存在持久化标识OID 加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在事务还未提交前变成持久态的。

c、脱管态

脱管态也称离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到

 

简单来说,这三种持久化对象的三种状态描述如下:

临时状态:

没有OID,和Session没有关系。

持久化状态:

有OID,和Session有关系。

脱管状态:

有OID,和Session没有关系。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值