首页 > 代码库 > Hibernate中ID生成策略
Hibernate中ID生成策略
四、ID生成策略
第一种:XML配置ID
通过为<id>元素增加<generator>子元素,该子元素拥有class属性。常用的class属性有:
(1)increment:用于为long、short、或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据的时候才能使用。在集群不要使用。(极少使用)
(2)native:让数据库自动选择identity,sequence,或者其他。
(3)uuid:128位的UUID算法,产生String类型ID
(4)identity:对于DB2、MySQL、SQL Server、Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long、short或者int类型。
sequence:在Oracel,PostgreSQL,SAP,DB,Mckio中使用序列(sequence),而在Interbase中使用生成器(generator),返回的标识符是long、short或者是int类型。
小实验1:
(1)创建Student.java
package com.zgy.hibernate.model;
public class Student {
private String id;
private String name;
private int age;
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
(2)在Student.hbm.xml中,为<id>配置其generator的class为uuid
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zgy.hibernate.model">
<class name="Student" table="student">
<id name="id" column="id">
<generator class="uuid"></generator>
</id>
<property name="name" column="name"></property>
<property name="age" column="age"></property>
<property name="score" column="score"></property>
</class>
</hibernate-mapping>
(3)测试
package com.zgy.hibernate.model;
import static org.junit.Assert.*;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class HibernateIDTest {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass(){
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void testStudent() {
Student s = new Student();
s.setName("张三");
s.setAge(20);
s.setScore(90);
Session session = sf.openSession();
session.beginTransaction();
session.save(s);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass(){
sf.close();
}
}
(4)验证
select * from student;
+-----------------------------------------------+--------+------+------+
| id | name | age | score |
+------------------------------------------------+------+-------+------+
| 4028dae54aa322d1014aa322d5a50000 | 张三 | 20 | 90 |
+----------------------------------+------+-----+-------+------+------+
desc student;
数据插入成功,id类型为varchar(255),主键
小实验2:
(1)修改Student.java。将id修改为int类型
package com.zgy.hibernate.model;
public class Student {
private int id;
private String name;
private int age;
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
(2)在Student.hbm.xml中,为<id>配置其generator的class为native
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zgy.hibernate.model">
<class name="Student" table="student">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="age" column="age"></property>
<property name="score" column="score"></property>
</class>
</hibernate-mapping>
(3)测试(删除student表)
(4)验证
select * from student;
+----+------+-------+-------+
| id | name | age | score |
+----+------+-------+-------+
| 1 | 张三 | 20 | 90 |
+----+------+-----+--------+
desc student;
数据插入成功,id为int(11)类型,主键,Auto_increment
第二种:Annotation配置ID
@GeneratedValue,默认的策略是auto,auto相当于XML中配置的native。
小实验1:
(1)编写Teacher.java。在getId()方法上添加@GeneratedValue
package com.zgy.hibernate.model;
import java.util.Date;
import javax.annotation.Generated;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@Table(name="_teacher")
public class Teacher {
private int id;
private String name;
private String title;
private String address;
private String wifeName;
private Date birth;
private ZhiCheng zhiCheng;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="_name")
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
@Temporal(TemporalType.DATE)
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Enumerated(EnumType.STRING)
public ZhiCheng getZhiCheng() {
return zhiCheng;
}
public void setZhiCheng(ZhiCheng zhiCheng) {
this.zhiCheng = zhiCheng;
}
}
(2)编写TeacherTesting.java,用于测试
package com.zgy.hibernate.model;
import static org.junit.Assert.*;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class TeacherTesting {
public static SessionFactory sf = null;
@BeforeClass
public static void beforeClass(){
sf = new AnnotationConfiguration().configure().buildSessionFactory();
}
@Test
public void test() {
Teacher t = new Teacher();
t.setName("t1");
t.setTitle("高级");
t.setAddress("北京");
t.setBirth(new Date());
t.setZhiCheng(ZhiCheng.A);
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
}
@AfterClass
public static void afterClass(){
sf.close();
}
}
(3)验证
select * from _teacher;
desc _teacher;
数据插入成功,id为int(11),主键,auto_increment
在使用Annotation的时候,除了使用auto策略,还可以使用increment,identity,sequence,table等等。
小实验2:
(1)修改Teacher.java.修改策略为identity
package com.zgy.hibernate.model;
import java.util.Date;
import javax.annotation.Generated;
import javax.persistence.Column;
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.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@Table(name="_teacher")
public class Teacher {
private int id;
private String name;
private String title;
private String address;
private String wifeName;
private Date birth;
private ZhiCheng zhiCheng;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="_name")
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
@Temporal(TemporalType.DATE)
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Enumerated(EnumType.STRING)
public ZhiCheng getZhiCheng() {
return zhiCheng;
}
public void setZhiCheng(ZhiCheng zhiCheng) {
this.zhiCheng = zhiCheng;
}
}
(2)测试
(3)验证
select * from _teacher;
desc _teacher;
使用table策略:
@javax.persistence.TableGenerator(
name="Teacher_GEN",
table="GENERATOR_TABLE",
pkColumnName="pkkey",
valueColumnName="pkvalue",
pkColumnValue=http://www.mamicode.com/"Teacher",
allocationSize=1
)
以上Annotation的意义:首先是定义了一个generator,该generator的名字叫做Teacher_GEN,生成一张表,表名为GENERATOR_TABLE,该表有两个字段,分别为pkColumnName和valueColumnName。这个表的第一条数据是:Teacher , 1。其下一条数据的步长值,即Teacher表的下一条数据的值会是2
小实验3:
(1)修改Teacher.java类
package com.zgy.hibernate.model;
import java.util.Date;
import javax.annotation.Generated;
import javax.persistence.Column;
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.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
@Entity
@javax.persistence.TableGenerator(
name="Teacher_GEN",
table="GENERATOR_TABLE",
pkColumnName="pkkey",
valueColumnName="pkvalue",
pkColumnValue=http://www.mamicode.com/"Teacher",
allocationSize=1
)
public class Teacher {
private int id;
private String name;
private String title;
private String address;
private String wifeName;
private Date birth;
private ZhiCheng zhiCheng;
@Id
@GeneratedValue(strategy=GenerationType.TABLE,generator="Teacher_GEN")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name="_name")
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getWifeName() {
return wifeName;
}
public void setWifeName(String wifeName) {
this.wifeName = wifeName;
}
@Temporal(TemporalType.DATE)
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Enumerated(EnumType.STRING)
public ZhiCheng getZhiCheng() {
return zhiCheng;
}
public void setZhiCheng(ZhiCheng zhiCheng) {
this.zhiCheng = zhiCheng;
}
}
(2)测试
(3)验证
查看hibernate执行过程中产生的sql语句
Hibernate: select pkvalue from GENERATOR_TABLE where pkkey = ‘Teacher‘ for update
Hibernate: insert into GENERATOR_TABLE(pkkey, pkvalue) values(‘Teacher‘, ?)
Hibernate: update GENERATOR_TABLE set pkvalue = ? where pkvalue = ? and pkkey = ‘Teacher‘
Hibernate: select pkvalue from GENERATOR_TABLE where pkkey = ‘Teacher‘ for update
Hibernate: update GENERATOR_TABLE set pkvalue = ? where pkvalue = ? and pkkey = ‘Teacher‘
Hibernate: insert into Teacher (address, birth, _name, title, wifeName, zhiCheng, id) values (?, ?, ?, ?, ?, ?, ?)
查看数据表
select * from generator_table;
select * from teacher;
Hibernate中ID生成策略