posts - 2,  comments - 0,  trackbacks - 0
          Hibernate的主鍵生成策略有好幾種:
          1) assigned
          2) hilo
          3) seqhilo
          4) increment
          5) identity
          6) sequence
          7) native
          8) uuid.hex
          9) uuid.string
          10) foreign
          一般而言,利用uuid.hex方式生成主鍵將提供最好的性能和數據庫平臺適
          應性。另外由于常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提
          供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。我們可以在數
          據庫提供的主鍵生成機制上,采用generator-class=native的主鍵生成方式。
          不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,
          大量并發insert數據時可能會引起表之間的互鎖。
          數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀
          態(如對于自增型主鍵而言,此內部表中就維護著當前的最大值和遞增量),
          之后每次插入數據會讀取這個最大值,然后加上遞增量作為新記錄的主鍵,之
          后再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據
          庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生
          了較大影響。
          因此,對于并發Insert要求較高的系統,推薦采用uuid.hex 作為主鍵生成
          機制。
          另外我們可以擴展Hibernate的類來做自己的主鍵生成策略:
          java 代碼
           
          1. package com.gsta.eshore.framework.util.uid;  
          2. import java.io.Serializable;  
          3. import org.hibernate.engine.SessionImplementor;  
          4. import org.hibernate.id.AbstractUUIDGenerator;  
          5. import org.hibernate.id.Configurable;  
          6. import org.hibernate.id.IdentifierGenerator;  
          7. import java.util.Properties;  
          8. import org.hibernate.Hibernate;  
          9. import org.hibernate.dialect.Dialect;  
          10. import org.hibernate.type.Type;  
          11. import org.hibernate.util.PropertiesHelper;  
          12. /** 
          13.  * <b>uuid</b><br> 
          14. * @author hwq 
          15.  */  
          16. public class UIDGenerator extends AbstractUUIDGenerator implements Configurable {  
          17.     private static long lastTime = System.currentTimeMillis();  
          18.     private static short lastCount = -32768;  
          19.     private static Object mutex = new Object();  
          20.     private static long ONE_SECOND = 1000L;  
          21.     private String sep = "";  
          22.     public Serializable generate(SessionImplementor session, Object obj) {  
          23.         long l = 0L;  
          24.         short word0 = 0;  
          25.         int i = 0;  
          26.         synchronized(mutex)  
          27.         {  
          28.             if(lastCount == 32767)  
          29.             {  
          30.                 for(boolean flag = false; !flag;)  
          31.                 {  
          32.                     l = System.currentTimeMillis();  
          33.                     if(l < lastTime + ONE_SECOND)  
          34.                     {  
          35.                         try  
          36.                         {  
          37.                             Thread.currentThread();  
          38.                             Thread.sleep(ONE_SECOND);  
          39.                         }  
          40.                         catch(InterruptedException interruptedexception) { }  
          41.                     } else  
          42.                     {  
          43.                         lastTime = l;  
          44.                         lastCount = -32768;  
          45.                         flag = true;  
          46.                     }  
          47.                 }  
          48.             } else  
          49.             {  
          50.                 l = lastTime;  
          51.             }  
          52.             word0 = lastCount++;  
          53.             i = getHostUniqueNum();  
          54.         }  
          55.         String s = Integer.toString(i, 16) + sep + Long.toString(l, 16) + sep + Integer.toString(word0, 16);  
          56.         if(s.length() > 24)  
          57.             s = s.substring(s.length() - 24);  
          58.         return s;  
          59.     }  
          60.     public Serializable generate_old(SessionImplementor session, Object obj) {  
          61.         String name = obj.getClass().getName();  
          62.         return new StringBuffer(64)  
          63.             .append(name.substring(name.lastIndexOf('.')+1)).append(sep)  
          64.             .append((short)getIP()).append(sep)  
          65.             .append(Math.abs((short)getJVM())).append(sep)  
          66.             .append(getCount())   
          67.             .toString();  
          68.     }  
          69.     private static int getHostUniqueNum()  
          70.     {  
          71.         return (new Object()).hashCode();  
          72.     }  
          73.     public void configure(Type type, Properties params, Dialect d) {  
          74.         sep = PropertiesHelper.getString("separator", params, "");  
          75.     }  
          76.     public static void main( String[] args ) throws Exception {  
          77.         Properties props = new Properties();  
          78.         props.setProperty("separator""");  
          79.         IdentifierGenerator gen = new UIDGenerator();  
          80.         ( (Configurable) gen ).configure(Hibernate.STRING, props, null);  
          81.         IdentifierGenerator gen2 = new UIDGenerator();  
          82.         ( (Configurable) gen2 ).configure(Hibernate.STRING, props, null);  
          83.         for ( int i=0; i<10; i++) {  
          84.             String id = (String) gen.generate(null, gen);  
          85.             System.out.println(id);  
          86.             String id2 = (String) gen2.generate(null, gen2);  
          87.             System.out.println(id2);  
          88.         }  
          89.     }  
          90. }  
          這個類必須要擴展AbstractUUIDGenerator并實現Configurable接口,在generate方法中生成我們想要的主鍵。
          在hibernate的配置文件中要做以下的配置:
          xml 代碼
           
          1. <id name="id" type="java.lang.String">  
          2.       <column name="id" length="24" />  
          3.       <generator class="com.gsta.eshore.framework.util.uid.UIDGenerator"><param name="separator">-</param></generator>  
          4.   </id>  
          Generator的類要引用UIDGenerator,并且可以帶參數生成主鍵,示例是根據時間,Ip等生成一個24位的字符串。這樣做的靈活性大大提高了,提供了最好的性能和數據庫平臺適應性。
          但是有時候我們在保存一條記錄的時候是不能指定主鍵的,因為它的主鍵要來源于其他的表的主鍵,(hibernate推薦用代理主鍵,但是有時候設計的時候沒有用到)。這個時候的主鍵生成策略就要是assigned了。為了保持主鍵的連貫性,我總不能又用另外一種主鍵生成策略吧。
          仿照上面的類,我們做一個生成24為隨機字符串的類。
          java 代碼
           
          1. package com.gsta.eshore.framework.util.uid;  
          2. public class UID  
          3. {  
          4.     private static long lastTime = System.currentTimeMillis();  
          5.     private static short lastCount = -32768;  
          6.     private static Object mutex = new Object();  
          7.     private static long ONE_SECOND = 1000L;  
          8.     public UID()  
          9.     {  
          10.     }  
          11.     public static String getUID()  
          12.     {  
          13.         long l = 0L;  
          14.         short word0 = 0;  
          15.         int i = 0;  
          16.         synchronized(mutex)  
          17.         {  
          18.             if(lastCount == 32767)  
          19.             {  
          20.                 for(boolean flag = false; !flag;)  
          21.                 {  
          22.                     l = System.currentTimeMillis();  
          23.                     if(l < lastTime + ONE_SECOND)  
          24.                     {  
          25.                         try  
          26.                         {  
          27.                             Thread.currentThread();  
          28.                             Thread.sleep(ONE_SECOND);  
          29.                         }  
          30.                         catch(InterruptedException interruptedexception) { }  
          31.                     } else  
          32.                     {  
          33.                         lastTime = l;  
          34.                         lastCount = -32768;  
          35.                         flag = true;  
          36.                     }  
          37.                 }  
          38.             } else  
          39.             {  
          40.                 l = lastTime;  
          41.             }  
          42.             word0 = lastCount++;  
          43.             i = getHostUniqueNum();  
          44.         }  
          45.         String s = Integer.toString(i, 16) + "`" + Long.toString(l, 16) + "`" + Integer.toString(word0, 16);  
          46.         if(s.length() > 24)  
          47.             s = s.substring(s.length() - 24);  
          48.         return s;  
          49.     }  
          50.     private static int getHostUniqueNum()  
          51.     {  
          52.         return (new Object()).hashCode();  
          53.     }  
          54.   
          55.    public static void main(String[] args) {  
          56.         for (int i = 0; i < 100; i++) {  
          57.             String uid=getUID();  
          58.             System.out.println(uid);  
          59.         }  
          60.         }  
          61. }  
          在save一個實體的時候調用entity.setId(UID.getUID())。
          呵呵,以后用hibernate就不用煩用什么主鍵生成策略了,自己做一個。
          posted on 2008-12-22 16:29 sunnyiric 閱讀(498) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 灌阳县| 遂川县| 隆子县| 铁岭县| 博客| 镇巴县| 邻水| 乃东县| 通州市| 茶陵县| 黄平县| 八宿县| 永泰县| 紫阳县| 墨脱县| 甘泉县| 枣强县| 建平县| 朝阳县| 微博| 石景山区| 镇原县| 乡宁县| 武山县| 神木县| 蒙山县| 土默特右旗| 鸡西市| 永登县| 会昌县| 贡觉县| 平阳县| 吉木乃县| 铅山县| 霸州市| 山东省| 额敏县| 寿阳县| 平远县| 嵩明县| 通江县|