A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 htb52110 于 2018-1-15 19:17 编辑

5、Hibernate持久化类和主键生成策略
5.1、持久化类
5.1.1、持久化类的概念【什么是持久化类】
Persistent Object  (PO)
持久化是将程序数据在持久状态和瞬时状态间转换的机制。
持久化类(persistent class):是指它的实例可以被hibernate持久化地保存到数据库中,并且能从数据库读取的类。
持久化类 = 实体类 + 映射文件。
5.1.2、持久化类的编写规则
a、提供一个无参数 public访问控制符的构造器:因为会用到反射。
b、提供一个标识属性,映射数据表主键字段 OID。
1)java区分两个对象是否是同一个对象,使用地址判断。
2)数据库区分两条记录是否一致,使用主键判断。
3)Hibernate区分持久化对象是否是同一个对象,根据唯一标识判断。
c、为所有属性提供public访问控制符的set/get方法,框架中存值和取值的时候使用。
d、标识属性应尽量使用基本数据类型的包装类型
使用基本类型的包装类型一个好处是,可以区分数据是没有传值默认生成的,还是本身就是这个默认值,比如一个表示数量的整数类型,如果使用int,没有传值时,数据库中会出现0,如果使用Integer,没有传值时,数据库中是null。
e、持久化类尽量不要使用final进行修饰。
用final修饰的类不能被继承,因此无法生成代理对象,由于延迟加载返回的是代理对象,因此延迟加载就会失效。
5.1.3、OID的作用
OID指的是与数据库中表的主键对应的属性。Hibernate框架它是通过OID来区分不同的PO对象,如果在内存中有两个相同的OID对象,那么hibernate认为它们是同一个对象。
5.1.4、Hibernate中get和load的区别
hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
5.2、主键生成策略
5.2.1、Hibernate中主键类型的介绍
Hibernate中定义的主键类型包括:自然主键和代理主键:
自然主键:具有业务含义的字段作为主键,比如:学号、身份证号
代理主键:不具有业务含义字段作为主键(例如 自增id),比如:mysql自增主键,oracle序列生成的主键、uuid()方法生成的唯一序列串
建议:企业开发中使用代理主键!
5.2.2、Hibernate中主键生成策略
主键生成器
描述
increment
代理主键。由hibernate维护一个变量,每次生成主键时自动以递增。
问题:如果有多个应用访问一个数据库,由于每个应用维护自己的主键,所以此时主键可能冲突。建议不采用。
优点:可以方便跨平台
缺点:不适合高并发访问
identity
代理主键。由底层数据库生成表识符。条件是数据库支持自动增长数据类型。比如:mysql的自增主键,oracle不支持主键自动生成。
如果数据库支持自增建议采用。
优点:由底层数据库维护,和hibernate无关
缺点:只能对支持自动增长的数据库有效,例如mysql
sequence
代理主键。Hibernate根据底层数据库序列生成标识符。条件是数据库支持序列。比如oracle的序列。
如果数据库支持序列建议采用。
优点:由底层数据库维护,和hibernate无关
缺点:数据库必须支持sequence方案例如oracle
native
代理主键。根据底层数据库对自动来选择identity、sequence、hilo
由于生成主键策略的控制权由hibernate控制,所以不建议采用。
优点:在项目中如果存在多个数据库时使用
缺点:效率比较低
uuid
代理主键。Hibernate采用128bit位的UUID算法来生成标识符。该算法
能够在网络环境中生成唯一的字符串标识符。
生成算法:
IP地址,JVM的启动时间(精确到1/4秒),系统时间和一个计数器值(在JVM中唯一)。
此策略可以保证生成主键的唯一性,并且提供了最好的数据库插入性能和数据库平台的无关性。建议采用。
优点:与数据库无关,方便数据库移植,效率高,不访问数据库就可以直接生成主键值,并且它能保证唯一性。
缺点:uuid长度大(32位),占用空间比较大,对应数据库中类型 char  varchar
assigned
自然主键。由java程序负责生成标识符。
不建议采用。
尽量在操作中避免手动对主键操作

6、Hibernate持久化对象的状态
6.1、持久化类三种状态介绍
6.1.1、瞬时态
也叫做临时态或自由态,它一般指我们new出来的对象,它不存在OID,与hibernate session无关联,在数据库中也无记录。它使用完成后,会被jvm直接回收掉,它只是用于信息携带。
简单说:无OID 与数据库中的信息无关联,不在session管理范围内。
6.1.2、持久态
在hibernate session管理范围内,它具有持久化标识OID它的特点,在事务未提交前一直是持久态,当它发生改变时,hibernate是可以检测到的。
简单说:有OID 由session管理,在数据库中有可能有,也有可有没有。

6.1.3、托管态【游离态】
也叫做游离态或离线态,它是指持久态对象失去了与session的关联,托管态对象它存在OID,在数据库中有可能存在,也有可能不存在。
对于托管态对象,它发生改变时hibernet不能检测到。
6.2、持久化类三种状态转换
解释:
6.2.1、瞬时态(new 出来的)
瞬时------>持久  save   saveOrUpdate
瞬时----->脱管(游离)  手动设置oid
6.2.2、持久态   它是由session管理
         持久------->瞬时   delete() 被删除后持久化对象不在建议使用
         持久----->脱管  注意:session它的缓存就是所说的一级缓存
                                               evict(清除一级缓存 中指定的一个对象)
                                               clear(清空一级缓存)
                                               close(关闭,清空一级缓存)
6.2.3、脱管态   (它是无法直接获取)
         脱管----->瞬时    直接将oid删除
         脱管----->持久  update  saveOrUpdate lock(过时)



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马