首页 > 代码库 > Hibernate中ID生成策略

Hibernate中ID生成策略

四、ID生成策略

第一种:XML配置ID

通过为<id>元素增加<generator>子元素,该子元素拥有class属性。常用的class属性有:

(1)increment:用于为longshort、或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据的时候才能使用。在集群不要使用。(极少使用)

 

(2)native:让数据库自动选择identitysequence,或者其他。

 

(3)uuid:128位的UUID算法,产生String类型ID 

 

(4)identity:对于DB2MySQLSQL ServerSybaseHypersonicSQL的内置标识字段提供支持。返回的标识符是longshort或者int类型。

 

sequence:OracelPostgreSQLSAPDBMckio中使用序列(sequence),而在Interbase中使用生成器(generator),返回的标识符是longshort或者是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>配置其generatorclassuuid

<?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>配置其generatorclassnative

 

<?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;

 

 

数据插入成功,idint(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;

 

数据插入成功,idint(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生成策略