increment:主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存着當前的最大值,之后每次需要生成主鍵的時候將此值加1作為主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那么由於各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重復異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用;
采用數據庫提供的主鍵生成機制。如DB2、SQL Server、MySQL中的主鍵生成機制。
采用數據庫提供的sequence 機制生成主鍵。如Oralce 中的Sequence。
hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。
4)seqhilo
與hilo 類似,通過hi/lo 算法實現的主鍵生成機制,只是主鍵歷史狀態保存在Sequence中,適用於支持Sequence的數據庫,如Oracle。
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼后以長度32 的字符串表示)作為主鍵。(跨數據庫)
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼后以長度32 的字符串表示)作為主鍵。(跨數據庫)
很少用;
根據數據庫選擇自動遞增算法,常用;(跨數據庫)
主鍵由外部程序負責生成,無需hibernate參與;
很少用;
使用外部表的字段作為主鍵。
主鍵按數值順序遞增。此方式的實現機制為在當前應用實例中維持一個變量,以保存着當前的最大值,之后每次需要生成主鍵的時候將此值加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 配置:
1 <id name="id" column="id"> 2 <generator class="uuid"/> 3 </id>
對應的JavaBean用String類型:
1 private String id; 2 public String getId() { 3 return id; 4 } 5 6 public void setId(String id) { 7 this.id = id; 8 }
native XML 配置:
<id name="id" column="id"> <generator class="native"/> </id>
對應的JavaBean用Integer/int類型:
1 private Integer id; 2 public Integer getId() { 3 return id; 4 } 5 6 public void setId(Integer id) { 7 this.id = id; 8 }
用 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 中的配置
1 <hibernate-mapping> 2 <class name="..." table="..." schema="..."> 3 <id name="userId" type="java.lang.Integer"> 4 <column name="USER_ID" precision="9" scale="0" /> 5 <generator class="sequence"> 6 <param name="sequence">Student_SEQ</param> 7 </generator> 8 </id> 9 <property ... /> 10 </class> 11 </hibernate-mapping>
3.2、復雜一點的主鍵生成器——TableGenerator
1 @javax.persistence.TableGenerator( 2 name="Teacher_GEN",//生成器名 3 table="GENERATOR_TABLE",//表名 4 pkColumnName = "pk_key",//第一個字段,key值 5 valueColumnName = "pk_value",//第二個字段,value值 6 pkColumnValue="Teacher",//一條記錄的第一個字段 7 allocationSize=1//增量 8 ) 9 @Id 10 @GeneratedValue(strategy=GenerationType.TABLE,generator="Teacher_GEN") 11 public Integer getId() { 12 return id; 13 }
初次使用該生成器,生成器找到對應的記錄,返回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()方法
1 package com.bjsxt.hibernate; 2 3 import java.io.Serializable; 4 5 public class StudentPK implements Serializable{ 6 7 private static final long serialVersionUID = -7950018142709463675L; 8 9 private Integer id; 10 11 private String name; 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 @Override 30 public boolean equals(Object o) { 31 if(o instanceof StudentPK){ 32 StudentPK pk = (StudentPK)o; 33 if(this.id == pk.getId() && this.name.equals(pk.getName())){ 34 return true; 35 } 36 } 37 return false; 38 } 39 40 @Override 41 public int hashCode() { 42 return this.name.hashCode(); 43 } 44 }
Student.hbm.xml
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping package="com.bjsxt.hibernate"> 7 <class name="Student" table="student"> 8 <composite-id name="pk" class="com.bjsxt.hibernate.StudentPK"> 9 <key-property name="id" /> 10 <key-property name="name" /> 11 </composite-id> 12 <property .../> 13 </class> 14 </hibernate-mapping>
插入操作:
1 @Test 2 public void testStudentSave(){ 3 StudentPK pk = new StudentPK(); 4 pk.setId(1); 5 pk.setName("zhangsan"); 6 Student s = new Student(); 7 s.setPk(pk); 8 ... 9 }
Annotation:
第一種方法:將組件類注解為@Embeddable,並將組件的屬性注解為@Id;
第二種方法:將組件的屬性注解為@EmbeddedId;
第三種方法:將類注解為@IdClass,並將該實體中所有屬於主鍵的屬性都注解為@Id;
3種方法的主鍵類同樣要需要實現Serializable接口,重寫hashCode()和equals()方法。
第一種方法例子:
TeacherPK

1 package com.bjsxt.hibernate; 2 3 import java.io.Serializable; 4 5 @Embeddable 6 public class TeacherPK implements Serializable{ 7 8 private static final long serialVersionUID = -3972276136768456123L; 9 10 private Integer id; 11 12 private String name; 13 14 public Integer getId() { 15 return id; 16 } 17 18 public void setId(Integer id) { 19 this.id = id; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 @Override 31 public boolean equals(Object o) { 32 if(o instanceof StudentPK){ 33 StudentPK pk = (StudentPK)o; 34 if(this.id == pk.getId() && this.name.equals(pk.getName())){ 35 return true; 36 } 37 } 38 return false; 39 } 40 41 @Override 42 public int hashCode() { 43 return this.name.hashCode(); 44 } 45 46 }
Teacher

1 package com.bjsxt.hibernate; 2 3 import java.util.Date; 4 5 import javax.persistence.EmbeddedId; 6 import javax.persistence.Entity; 7 import javax.persistence.EnumType; 8 import javax.persistence.Enumerated; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.GenerationType; 11 import javax.persistence.Id; 12 import javax.persistence.IdClass; 13 import javax.persistence.SequenceGenerator; 14 import javax.persistence.Temporal; 15 import javax.persistence.TemporalType; 16 17 @javax.persistence.TableGenerator( 18 name="Teacher_GEN",//生成器名 19 table="GENERATOR_TABLE",//表名 20 pkColumnName = "pk_key",//第一個字段,key值 21 valueColumnName = "pk_value",//第二個字段,value值 22 pkColumnValue="Teacher",//記錄值 23 allocationSize=1//增量 24 ) 25 26 @Entity 27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB") 28 public class Teacher { 29 private TeacherPK pk; 30 31 private String title; 32 33 private Date birthday; 34 35 private ZhiCheng zhicheng; 36 37 public String getTitle() { 38 return title; 39 } 40 41 @Id 42 public TeacherPK getPk() { 43 return pk; 44 } 45 46 public void setPk(TeacherPK pk) { 47 this.pk = pk; 48 } 49 50 public void setTitle(String title) { 51 this.title = title; 52 } 53 54 @Temporal(TemporalType.DATE) 55 public Date getBirthday() { 56 return birthday; 57 } 58 59 public void setBirthday(Date birthday) { 60 this.birthday = birthday; 61 } 62 63 @Enumerated(value=EnumType.STRING) 64 public ZhiCheng getZhicheng() { 65 return zhicheng; 66 } 67 68 public void setZhicheng(ZhiCheng zhicheng) { 69 this.zhicheng = zhicheng; 70 } 71 72 }
第二種方法例子:
TeacherPK

1 package com.bjsxt.hibernate; 2 3 import java.io.Serializable; 4 5 public class TeacherPK implements Serializable{ 6 7 private static final long serialVersionUID = -3972276136768456123L; 8 9 private Integer id; 10 11 private String name; 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 @Override 30 public boolean equals(Object o) { 31 if(o instanceof StudentPK){ 32 StudentPK pk = (StudentPK)o; 33 if(this.id == pk.getId() && this.name.equals(pk.getName())){ 34 return true; 35 } 36 } 37 return false; 38 } 39 40 @Override 41 public int hashCode() { 42 return this.name.hashCode(); 43 } 44 45 }
Teacher

1 package com.bjsxt.hibernate; 2 3 import java.util.Date; 4 5 import javax.persistence.EmbeddedId; 6 import javax.persistence.Entity; 7 import javax.persistence.EnumType; 8 import javax.persistence.Enumerated; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.GenerationType; 11 import javax.persistence.Id; 12 import javax.persistence.IdClass; 13 import javax.persistence.SequenceGenerator; 14 import javax.persistence.Temporal; 15 import javax.persistence.TemporalType; 16 17 @javax.persistence.TableGenerator( 18 name="Teacher_GEN",//生成器名 19 table="GENERATOR_TABLE",//表名 20 pkColumnName = "pk_key",//第一個字段,key值 21 valueColumnName = "pk_value",//第二個字段,value值 22 pkColumnValue="Teacher",//記錄值 23 allocationSize=1//增量 24 ) 25 26 @Entity 27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB") 28 public class Teacher { 29 private TeacherPK pk; 30 31 private Integer id; 32 33 private String name; 34 35 private String title; 36 37 private Date birthday; 38 39 private ZhiCheng zhicheng; 40 41 public void setName(String name) { 42 this.name = name; 43 } 44 45 public String getTitle() { 46 return title; 47 } 48 49 50 @EmbeddedId 51 public TeacherPK getPk() { 52 return pk; 53 } 54 55 public void setPk(TeacherPK pk) { 56 this.pk = pk; 57 } 58 59 public void setTitle(String title) { 60 this.title = title; 61 } 62 63 @Temporal(TemporalType.DATE) 64 public Date getBirthday() { 65 return birthday; 66 } 67 68 public void setBirthday(Date birthday) { 69 this.birthday = birthday; 70 } 71 72 @Enumerated(value=EnumType.STRING) 73 public ZhiCheng getZhicheng() { 74 return zhicheng; 75 } 76 77 public void setZhicheng(ZhiCheng zhicheng) { 78 this.zhicheng = zhicheng; 79 } 80 81 }
第三種方法例子:
TeacherPK

1 package com.bjsxt.hibernate; 2 3 import java.io.Serializable; 4 5 public class TeacherPK implements Serializable{ 6 7 private static final long serialVersionUID = -3972276136768456123L; 8 9 private Integer id; 10 11 private String name; 12 13 public Integer getId() { 14 return id; 15 } 16 17 public void setId(Integer id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 @Override 30 public boolean equals(Object o) { 31 if(o instanceof StudentPK){ 32 StudentPK pk = (StudentPK)o; 33 if(this.id == pk.getId() && this.name.equals(pk.getName())){ 34 return true; 35 } 36 } 37 return false; 38 } 39 40 @Override 41 public int hashCode() { 42 return this.name.hashCode(); 43 } 44 45 }
Teacher

1 package com.bjsxt.hibernate; 2 3 import java.util.Date; 4 5 import javax.persistence.EmbeddedId; 6 import javax.persistence.Entity; 7 import javax.persistence.EnumType; 8 import javax.persistence.Enumerated; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.GenerationType; 11 import javax.persistence.Id; 12 import javax.persistence.IdClass; 13 import javax.persistence.SequenceGenerator; 14 import javax.persistence.Temporal; 15 import javax.persistence.TemporalType; 16 17 @javax.persistence.TableGenerator( 18 name="Teacher_GEN",//生成器名 19 table="GENERATOR_TABLE",//表名 20 pkColumnName = "pk_key",//第一個字段,key值 21 valueColumnName = "pk_value",//第二個字段,value值 22 pkColumnValue="Teacher",//記錄值 23 allocationSize=1//增量 24 ) 25 26 @Entity 27 @SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB") 28 @IdClass(StudentPK.class) 29 public class Teacher { 30 private Integer id; 31 32 private String name; 33 34 private String title; 35 36 private Date birthday; 37 38 private ZhiCheng zhicheng; 39 40 @Id 41 public Integer getId() { 42 return id; 43 } 44 45 public void setId(Integer id) { 46 this.id = id; 47 } 48 49 @Id 50 public String getName() { 51 return name; 52 } 53 54 public void setName(String name) { 55 this.name = name; 56 } 57 58 public String getTitle() { 59 return title; 60 } 61 62 public void setTitle(String title) { 63 this.title = title; 64 } 65 66 @Temporal(TemporalType.DATE) 67 public Date getBirthday() { 68 return birthday; 69 } 70 71 public void setBirthday(Date birthday) { 72 this.birthday = birthday; 73 } 74 75 @Enumerated(value=EnumType.STRING) 76 public ZhiCheng getZhicheng() { 77 return zhicheng; 78 } 79 80 public void setZhicheng(ZhiCheng zhicheng) { 81 this.zhicheng = zhicheng; 82 } 83 84 }
鏈接: http://pan.baidu.com/s/1qYayZk4 密碼: ta5c
所需jar包鏈接: http://pan.baidu.com/s/1hr35oVU 密碼: yhsf