四、ID生成策略 第一种:XML配置ID 通过为id元素增加generator子元素,该子元素拥有class属性。常用的class属性有: (1)increment:用于为long、short、或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据的时候才能使用。在集群不要使用。(极
四、ID生成策略
第一种:XML配置ID
通过为元素增加子元素,该子元素拥有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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 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中,为配置其generator的class为uuid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?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)测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 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)验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | select * from student;
+-----------------------------------------------+--------+------+------+
| id | name | age | score |
+------------------------------------------------+------+-------+------+
| 4028dae54aa322d1014aa322d5a50000 | 张三 | 20 | 90 |
+----------------------------------+------+-----+-------+------+------+
desc student;
|
ログイン後にコピー
数据插入成功,id类型为varchar(255),主键
小实验2:
(1)修改Student.java。将id修改为int类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 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中,为配置其generator的class为native
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?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)验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 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,用于测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 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;
impo【本文来自鸿网互联 (http:
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)验证
1 2 3 4 5 | select * from _teacher;
desc _teacher;
|
ログイン後にコピー
数据插入成功,id为int(11),主键,auto_increment
在使用Annotation的时候,除了使用auto策略,还可以使用increment,identity,sequence,table等等。
小实验2:
(1)修改Teacher.java.修改策略为identity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 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)验证
1 2 3 | select * from _teacher;
desc _teacher;
|
ログイン後にコピー
使用table策略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @javax.persistence.TableGenerator(
name= "Teacher_GEN" ,
table= "GENERATOR_TABLE" ,
pkColumnName= "pkkey" ,
valueColumnName= "pkvalue" ,
pkColumnValue= "Teacher" ,
allocationSize=1
)
|
ログイン後にコピー
以上Annotation的意义:首先是定义了一个generator,该generator的名字叫做Teacher_GEN,生成一张表,表名为GENERATOR_TABLE,该表有两个字段,分别为pkColumnName和valueColumnName。这个表的第一条数据是:Teacher , 1。其下一条数据的步长值,即Teacher表的下一条数据的值会是2
小实验3:
(1)修改Teacher.java类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 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= "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 (?, ?, ?, ?, ?, ?, ?)
查看数据表
1 2 3 | select * from generator_table;
select * from teacher;
|
ログイン後にコピー