hibernate_ID生成策略
increment:主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用;
1)identity:
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL中的主键生成机制。
2)sequence
采用数据库提供的sequence 机制生成主键。如Oralce 中的Sequence。
3)hilo
hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
4)seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle。
5)uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。(跨数据库)
6)uuid.hex
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字符串表示)作为主键。(跨数据库)
7)guid
很少用;
8)native
根据数据库选择自动递增算法,常用;(跨数据库)
9)assigned
主键由外部程序负责生成,无需hibernate参与;
10)select
很少用;
11)foreign
使用外部表的字段作为主键。
12)sequence-identity 很少用;
13)increment
主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护主键状态,不同实例可能生成同样的主键,从而造成主键重复异常。因此,如果同一数据库有多个实例访问,此方式必须避免使用。
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应性。
另外由于常用的数据库,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主键生成机制(Auto-Increase 字段或者Sequence)。我们可以在数据库提供的主键生成机制上,采用generator-class=native的主键生成方式。
hibernate 的说明如下:
不过值得注意的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据时可能会引起表之间的互锁。数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了较大影响。因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生成机制。
路径:hibernate-distribution-3.3.2.GA/documentation/manual/zh-CN/html_single/index.html#mapping-declaration-id
截图:




uuid XML 配置:
<id name="id" column="id">
<generator class="uuid"/>
</id>
对应的JavaBean用String类型:
private String id;
public String getId() {
return id;
} public void setId(String id) {
this.id = id;
}
native XML 配置:
<id name="id" column="id">
<generator class="native"/>
</id>
对应的JavaBean用Integer/int类型:
private Integer id;
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
}
用 MySQL 数据库,hibernate自动生成的建_student表的语句:

连接Oracle数据库进行测试:
1、重新在 hibernate.cfg.xml文件中修改Oracle的连接配置,具体配置驱动、url、username、password的配置参考:
hibernate-distribution-3.3.2.GA\project\etc\hibernate.properties

2、java bean的属性配置要符合oracle表和字段的命名规范;
3、ID 配置:
XML 的跟上面的一样;
注解:默认就是AUTO(相当于native),可以不用写,此时ID生成的sequence是hibernate_sequence;
还有 IDENTITY(只能用在MySQL和SQL Server等支持IDENTITY的数据库中,Oracle就用不了)、SEQUENCE、TABLE
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
3.1、如果要为 model ID 指定确定的sequence,而不是去用默认的 hibernate_sequence,配置如下:
注解:
model头:name 表示这个sequence生成器的名字,sequenceName 是指明序列在数据库中的名字
@Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
ID上的配置:
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")
public Integer getId() {
return id;
}
XML:在 hibernate.cfg.xml 中的配置
<hibernate-mapping>
<class name="..." table="..." schema="...">
<id name="userId" type="java.lang.Integer">
<column name="USER_ID" precision="9" scale="0" />
<generator class="sequence">
<param name="sequence">Student_SEQ</param>
</generator>
</id>
<property ... />
</class>
</hibernate-mapping>
3.2、复杂一点的主键生成器——TableGenerator
@javax.persistence.TableGenerator(
name="Teacher_GEN",//生成器名
table="GENERATOR_TABLE",//表名
pkColumnName = "pk_key",//第一个字段,key值
valueColumnName = "pk_value",//第二个字段,value值
pkColumnValue="Teacher",//一条记录的第一个字段
allocationSize=1//增量
)
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="Teacher_GEN")
public Integer getId() {
return id;
}

初次使用该生成器,生成器找到对应的记录,返回value值1,同时value加上对应的增量。
3.3 联合主键
XML:一个表中的两个字段做主键,例子中取Student中的id、name做主键,创建一个StudentPK做主键类,在Student中配置好联合主键
Student
package com.bjsxt.hibernate;
public class Student {
private StudentPK pk;
private Integer age;
public StudentPK getPk() {
return pk;
}
public void setPk(StudentPK pk) {
this.pk = pk;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
StudentPK 需要实现Serializable接口,重写hashCode()和equals()方法
package com.bjsxt.hibernate;
import java.io.Serializable;
public class StudentPK implements Serializable{
private static final long serialVersionUID = -7950018142709463675L;
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(o instanceof StudentPK){
StudentPK pk = (StudentPK)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())){
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.bjsxt.hibernate">
<class name="Student" table="student">
<composite-id name="pk" class="com.bjsxt.hibernate.StudentPK">
<key-property name="id" />
<key-property name="name" />
</composite-id>
<property .../>
</class>
</hibernate-mapping>
插入操作:
@Test
public void testStudentSave(){
StudentPK pk = new StudentPK();
pk.setId(1);
pk.setName("zhangsan");
Student s = new Student();
s.setPk(pk);
...
}
Annotation:
第一种方法:将组件类注解为@Embeddable,并将组件的属性注解为@Id;
第二种方法:将组件的属性注解为@EmbeddedId;
第三种方法:将类注解为@IdClass,并将该实体中所有属于主键的属性都注解为@Id;
3种方法的主键类同样要需要实现Serializable接口,重写hashCode()和equals()方法。
第一种方法例子:
TeacherPK
package com.bjsxt.hibernate; import java.io.Serializable; @Embeddable
public class TeacherPK implements Serializable{ private static final long serialVersionUID = -3972276136768456123L; private Integer id; private String name; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public boolean equals(Object o) {
if(o instanceof StudentPK){
StudentPK pk = (StudentPK)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())){
return true;
}
}
return false;
} @Override
public int hashCode() {
return this.name.hashCode();
} }
Teacher
package com.bjsxt.hibernate; import java.util.Date; import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; @javax.persistence.TableGenerator(
name="Teacher_GEN",//生成器名
table="GENERATOR_TABLE",//表名
pkColumnName = "pk_key",//第一个字段,key值
valueColumnName = "pk_value",//第二个字段,value值
pkColumnValue="Teacher",//记录值
allocationSize=1//增量
) @Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
public class Teacher {
private TeacherPK pk; private String title; private Date birthday; private ZhiCheng zhicheng; public String getTitle() {
return title;
} @Id
public TeacherPK getPk() {
return pk;
} public void setPk(TeacherPK pk) {
this.pk = pk;
} public void setTitle(String title) {
this.title = title;
} @Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} @Enumerated(value=EnumType.STRING)
public ZhiCheng getZhicheng() {
return zhicheng;
} public void setZhicheng(ZhiCheng zhicheng) {
this.zhicheng = zhicheng;
} }
第二种方法例子:
TeacherPK
package com.bjsxt.hibernate;
import java.io.Serializable;
public class TeacherPK implements Serializable{
private static final long serialVersionUID = -3972276136768456123L;
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(o instanceof StudentPK){
StudentPK pk = (StudentPK)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())){
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
Teacher
package com.bjsxt.hibernate; import java.util.Date; import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; @javax.persistence.TableGenerator(
name="Teacher_GEN",//生成器名
table="GENERATOR_TABLE",//表名
pkColumnName = "pk_key",//第一个字段,key值
valueColumnName = "pk_value",//第二个字段,value值
pkColumnValue="Teacher",//记录值
allocationSize=1//增量
) @Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
public class Teacher {
private TeacherPK pk; private Integer id; private String name; private String title; private Date birthday; private ZhiCheng zhicheng; public void setName(String name) {
this.name = name;
} public String getTitle() {
return title;
} @EmbeddedId
public TeacherPK getPk() {
return pk;
} public void setPk(TeacherPK pk) {
this.pk = pk;
} public void setTitle(String title) {
this.title = title;
} @Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} @Enumerated(value=EnumType.STRING)
public ZhiCheng getZhicheng() {
return zhicheng;
} public void setZhicheng(ZhiCheng zhicheng) {
this.zhicheng = zhicheng;
} }
第三种方法例子:
TeacherPK
package com.bjsxt.hibernate;
import java.io.Serializable;
public class TeacherPK implements Serializable{
private static final long serialVersionUID = -3972276136768456123L;
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if(o instanceof StudentPK){
StudentPK pk = (StudentPK)o;
if(this.id == pk.getId() && this.name.equals(pk.getName())){
return true;
}
}
return false;
}
@Override
public int hashCode() {
return this.name.hashCode();
}
}
Teacher
package com.bjsxt.hibernate; import java.util.Date; import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType; @javax.persistence.TableGenerator(
name="Teacher_GEN",//生成器名
table="GENERATOR_TABLE",//表名
pkColumnName = "pk_key",//第一个字段,key值
valueColumnName = "pk_value",//第二个字段,value值
pkColumnValue="Teacher",//记录值
allocationSize=1//增量
) @Entity
@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")
@IdClass(StudentPK.class)
public class Teacher {
private Integer id; private String name; private String title; private Date birthday; private ZhiCheng zhicheng; @Id
public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} @Id
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} @Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} @Enumerated(value=EnumType.STRING)
public ZhiCheng getZhicheng() {
return zhicheng;
} public void setZhicheng(ZhiCheng zhicheng) {
this.zhicheng = zhicheng;
} }
链接: http://pan.baidu.com/s/1qYayZk4 密码: ta5c
所需jar包链接: http://pan.baidu.com/s/1hr35oVU 密码: yhsf
hibernate_ID生成策略的更多相关文章
- 大家一起撸代码之——Hibernate各种主键生成策略与配置详解
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- Hibernate各种主键生成策略与配置详解
出自:http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前 ...
- hibernate主键生成策略(转载)
http://www.cnblogs.com/kakafra/archive/2012/09/16/2687569.html 1.assigned 主键由外部程序负责生成,在 save() 之前必须指 ...
- Hibernate各种主键生成策略与配置详解《转》
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- Hibernate之:各种主键生成策略与配置详解
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- Hibernate各种主键生成策略与配置详解【附1--<generator class="foreign">】
1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...
- 【转】Hibernate各种主键生成策略与配置详解
原文转自:Fra~~kaka's Blog 1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无 ...
- hibernate框架(4)---主键生成策略
主键生成策略 常见的生成策略分为六种 1.increment 由Hibernate从数据库中取出主键的最大值(每个session只取1次),以该值为基础,每次增量为1,在内存中生成主键,不依赖于底层的 ...
- Hibernate学习笔记2.4(Hibernate的Id生成策略)
通过设置告诉id该怎么设置. 1.通过xml方式 1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据 ...
随机推荐
- [原创]在Centos7上搭建私有的Gitlab服务器
前言 Git作为后起之秀,在版本控制领域占据了头把交椅.Github作为托管式的代码仓库,从代码安全性和网络传输等各个方面考虑,对于个人和公司来讲,具有一定的局限性.Gitlab提供的不同版本的安装包 ...
- sharepoint_study_3
SharePoint网页无法打开 描述:安装部署好SharePoint开发环境后,再修改计算机的机器名,重启计算机后,发现SharePoint网站不能打开. 解决:1.将机器名改回去,重启计算机,问题 ...
- HDU - 6186 前缀和位运算
异或操作蒙蔽了我的双眼 以至于没有第一时间想到前缀和与后缀和 水题做的不够多 #include<bits/stdc++.h> #define rep(i,j,k) for(register ...
- hdu2588 GCD
GCD Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- 基于vue-cli搭建路飞
一.项目搭建 1. 首先进入到项目要保存的文件夹,然后执行命令如下命令初始化项目 vue init webpack lufei 2. 命令执行后,除了第一个填一下项目名称,其他的一路选no,这样建立的 ...
- UML-1-面向对象分析和设计
1.关键词: OOA:Object-Oriented Analysis.面向对象分析.抽取对象或概念,如:航班系统包含 飞机(Plane).航班(Flight)等概念. OOD:Object-Orie ...
- RedisClient 连接redis 提示 ERR Client sent AUTH, but no password is set
- TOJ 2857 Stockbroker Grapevine
描述 Stockbrokers are known to overreact to rumours. You have been contracted to develop a method of s ...
- unity摄像机脚本
直接挂载在摄像机上面即可 1.摄像机自由平移 using UnityEngine; using System.Collections; /// <summary> /// 摄像机视角自由移 ...
- java url生成二维码保存到本地
http://blog.sina.com.cn/s/blog_5a6efa330102v1lb.html http://blog.csdn.net/about58238/article/details ...