一、主鍵類型
1.自然主鍵(主鍵本身就是表中的一個字段,實體中一個具體的屬性)
表中已經具有某字段,並且該字段具有業務含義作為主鍵,稱之為自然主鍵。
例如:在person表中的身份證號,既是唯一的,又可以單獨標識一個person
2.代理主鍵(主鍵不是實體中某個具體的屬性,而是一個不相關的字段)
表中原本不存在的字段,且不具備業務含義的字段作為主鍵,稱之為代理主鍵。更合理的方式是使用代理主鍵。
二、主鍵生成策略
主鍵生成策略,就是每條記錄錄入時,主鍵的生成規則。Hibernate中,提供了幾個內置的主鍵生成策略,其常用主鍵生成策略的名稱和描述如下
1.代理主鍵
identity(主鍵自增)
適用於long、short或int類型主鍵,采用底層數據庫本身提供的主鍵生成標識符。在DB2、MySQL、MS SQL Server、Sybase和HypersonicSQL數據庫中可以使用該生成器,該生成器要求在數據庫中把主鍵定義成為自增類型。Oracle沒有自動增長
sequence(序列)
適用於long、short或int類型主鍵,Hibernate根據底層數據庫序列生成標識符。條件是數據庫支持序列。如oralce、DB、SAP DB、PostgerSQL、McKoi中的sequence,MySQL這種不支持sequence
increment(主鍵自增,單線程,maxID+1)
適用於long、short或int類型主鍵,由Hibernate提供自動遞增的方式生成唯一標識符,每次增量為1。只有當沒有其他進程向同一張表中插入數據時才可以使用,不能再多線程環境下使用
hilo(主鍵自增,高低位算法)
hilo(高低位方式high low)是hibernate中最常用的一種生成方式,需要一張額外的表保存hi的值。保存hi值的表至少有一條記錄(只與第一條記錄有關),否則會出現錯誤。跨數據庫,hilo算法生成的標志只能在一個數據庫中保證唯一
native(hilo+identity+sequence三選一)
根據底層數據庫對自動生成標識符的能力來選擇i dentity、sequence、hilo三種生成器中的一種,適合跨數據庫平台開發
uuid(隨機字符串作主鍵)
Hibernate采用128位的UUID算法來生成標識符。該算法能夠在網絡環境中生成唯一的字符串標識符,其UUID被編碼為一個長度為32位的十六進制字符串。按照開放軟件基金會(OSF)制定的標准計算,用到了以太網卡地址、納秒級時間、芯片ID碼和許多可能的數字
uuid長度大,占用空間大,跨數據庫,不用訪問數據庫就生成主鍵值,所以效率高且能保證唯一性,移植非常方便,推薦使用。
guid(全球唯一標識符)
全球唯一標識符,也稱作 UUID,是一個128位長的數字,用16進制表示。算法的核心思想是結合機器的網卡、當地時間、一個隨即數來生成GUID。
Hibernate在維護主鍵時,先查詢數據庫,獲得一個uuid字符串,該字符串就是主鍵值,該值唯一,缺點長度較大,支持數據庫有限,優點同uuid,跨數據庫,但是仍然需要訪問數據庫。注意:長度因數據庫不同而不同。
需要數據庫支持查詢uuid,生成時需要查詢數據庫,效率沒有uuid高,推薦使用uuid。
2.自然主鍵
assigned(用戶手動錄入)
由Java程序負責生成標識符,Hibernate不管理主鍵,用戶手動設置主鍵的值。如果不指定id元素的generator屬性,則默認使用該主鍵生成策略。
內容:
1 assigned
數據類型不限、保存前必須賦值
2 identity
數字,無需賦值
3 sequence
數字,無需賦值, 默認使hibernate_sequence這個序列,
也可以通過sequence/sequence_name參數賦值
4 increment
數字,無需賦值
5 uuid/uuid.hex (是由容器自動生成的一個32位的字符串,.hex代表的是十六進制)
32位的字符串,無需賦值,
6 native
等於identity+sequence
導入SessionFactoryUtils類
1 public class SessionFactoryUtils { 2 private static SessionFactory sessionFactory; 3 // 存放當前會話 4 private static ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); 5 static { 6 Configuration cfg = new Configuration(); 7 Configuration configure = cfg.configure("/hibernate.cfg.xml"); 8 sessionFactory = configure.buildSessionFactory(); 9 } 10 11 public static Session openSession() { 12 Session session = threadLocal.get(); 13 if (null == session) { 14 session = sessionFactory.openSession(); 15 threadLocal.set(session); 16 } 17 return session; 18 } 19 20 public static void closeSession() { 21 Session session = threadLocal.get(); 22 if (null != session) { 23 if (session.isOpen()) { 24 session.close(); 25 } 26 threadLocal.set(null); 27 } 28 } 29 30 public static void main(String[] args) { 31 Session session = openSession(); 32 System.out.println(session.isConnected()); 33 closeSession(); 34 } 35 36 }
這個類在學習hibernate的過程中所用(整合SSH框架之前用)
作用:可以用來檢測所寫的映射文件是否正確;
然后創建好實體類和實體映射文件
學生類:
1 public class Student implements Serializable { 2 3 private Integer sid; 4 private String sname; 5 public Integer getSid() { 6 return sid; 7 } 8 public void setSid(Integer sid) { 9 this.sid = sid; 10 } 11 public String getSname() { 12 return sname; 13 } 14 public void setSname(String sname) { 15 this.sname = sname; 16 } 17 @Override 18 public String toString() { 19 return "Worker [sid=" + sid + ", sname=" + sname + "]"; 20 } 21 }
工人類:
1 public class Worker implements Serializable{ 2 private String wid; 3 private String wname; 4 public String getWid() { 5 return wid; 6 } 7 public void setWid(String wid) { 8 this.wid = wid; 9 } 10 public String getWname() { 11 return wname; 12 } 13 public void setWname(String wname) { 14 this.wname = wname; 15 } 16 @Override 17 public String toString() { 18 return "Worker [wid=" + wid + ", wname=" + wname + "]"; 19 } 20 21 22 23 }
兩個實體映射文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="two.entity.Student" table="t_hibernate_student"> 7 <id name="sid" type="java.lang.Integer" column="sid"> 8 <!-- <generator class="assigned" />--> 9 <!-- <generator class="identity" /> --> 10 <generator class="increment" /> 11 <!-- <generator class="sequence" /> --> 12 <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 13 </generator> --> 14 <!-- <generator class="com.javaxl.two.id.Myts" /> --> 15 </id> 16 <property name="sname" type="java.lang.String" column="sname"> 17 </property> 18 </class> 19 </hibernate-mapping>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping> 6 <class name="two.entity.Worker" table="t_hibernate_work"> 7 <id name="wid" type="java.lang.String" column="wid"> 8 <!-- <generator class="uuid" /> --> 9 <!-- <generator class="sequence" /> --> 10 <!-- <generator class="sequence" > <param name="sequence_name">aaa</param> 11 </generator> --> 12 <generator class="two.id.Myts" /> 13 </id> 14 15 <property name="wname" type="java.lang.String" column="wname"> 16 </property> 17 </class> 18 </hibernate-mapping>
dao方法
1 public class DemoDao { 2 /** 3 * 添加學生 4 * @param stu 5 * @return 6 */ 7 public Serializable addStudent(Student stu) { 8 Session session=SessionFactoryUtils.openSession(); 9 Transaction transaction=session.beginTransaction(); 10 Serializable saveId=session.save(stu); 11 transaction.commit(); 12 session.close(); 13 return saveId; 14 } 15 /** 16 * 添加工人 17 * @param worker 18 * @return 19 */ 20 public Serializable addWork(Worker worker) { 21 Session session=SessionFactoryUtils.openSession(); 22 Transaction transaction=session.beginTransaction(); 23 Serializable saveId=session.save(worker); 24 transaction.commit(); 25 session.close(); 26 return saveId; 27 } 28 29 30 31 // public static void teststudent(String[] args) { 32 // 33 // DemoDao dao=new DemoDao(); 34 // Student stu=new Student(); 35 //// stu.setSid(4); 36 // stu.setSname("張三"); 37 // dao.addStudent(stu); 38 // System.out.println(dao.addStudent(stu)); 39 // } 40 public static void main(String[] args) { 41 DemoDao dao=new DemoDao(); 42 Worker worker=new Worker(); 43 worker.setWname("啊哈哈哈"); 44 System.out.println(dao.addWork(worker)); 45 } 46 47 48 }
各位大佬們可以一一去試
最后一個自定義主鍵生成器
需要創建一個類來設置你需要變成的id格式
如下:
public class Myts implements IdentifierGenerator { @Override public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { // TODO Auto-generated method stub SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return "shop_book_"+sdf.format(new Date()); } }
在dao方法類運行:
顯示如下: