主键生成策略
increment
identity
sequence
native
uuid
assigned
1) increment
由hibernate完成 主键递增,
原理:select max(id) , insert时max(id)+1 ,完成主键递增
优点:跨数据库
缺点:多线程并发访问问题(第一个线程执行成功,第二个线程报错)
2) identity
由底层数据库来完成自增 ,要求数据库必须支持自增主键 mysql支持 ,oracle不支持
3) sequence
编号列生成由底层数据库提供序列,来完成主键自增,要求数据库必须支持序列 mysql不支持,oracle支持
create sequence myseq; 创建序列
insert into customer values (myseq.nextval); 插入数据时调用序列,序列+1
4) native
采用数据库支持自增策略, mysql就用identity 、oracle就用sequence
策略1) ---> 策略4) 要求数据库主键必须为数字 ,因为只有数字才能自增
5) uuid
32位 唯一字符串, 主键使用varchar 类型
真实开发中,用程序提供uuid值
6) assigned
手动指定主键的值,该主键一般有实际意义,例如订单单号(20160114-A002)20160114-B001 20160114-C002。
复合主键,是一种特殊 assigned类型 自然主键 (通常需要手动指定),PO类必须实现Serializable接口
<class name="cn.happy.entity.Person" table="person">
<composite-id>
<key-property name="firstname"></key-property>
<key-property name="secondname"></key-property>
</composite-id>
</class>
7)foreign
使用另外一个相关联的对象的标识符。它通常和 <one-to-one>
联合起来使用。
8)hilo
使用一个高/低位算法高效的生成 long
,short
或者 int
类型的标识符。给定一个表和字段(默认分别是hibernate_unique_key
和 next_hi
)作为高位值的来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
9)select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
java对象的三种状态
持久态:
Student stu=new Student()
Session.save(stu);
Session以及数据库都有
游离态:
stu.setId(1);
Session.close();
Session没有 数据库中有
瞬时态:
Student stu=new Student()
体现:在Session中以及DB都没有
三种状态之间的转换:
该图从类型上划分为“活动图”
使用new关键字构建对象,该对象的状态是瞬时状态。
1 瞬时状态转为持久状态
使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态。
使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态。
2 持久状态转为瞬时状态
执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。
3 持久状态转为游离状态
吃行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态。
4 游离状态转为持久状态
重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象相关联。
5 游离状态转为瞬时状态
执行Session对象的delete()方法,对象由游离状态转为瞬时状态。
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理。