<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Blog for Alex Wan

    Let life be beautiful like summer flowers and death like autumn leaves.

    統計

    留言簿(10)

    BlogJava

    Blogs

    DIV+CSS

    JQuery相關

    友情鏈接

    常去的地方

    數據供應

    閱讀排行榜

    評論排行榜

    [hibernate]hibernate中自定義主鍵生成器

    背景:
    Hibernate(目前使用的版本是3.2)中提供了多種生成主鍵的方式.在下面的文章中有列出來
    [hibernate]Hibernate主鍵生成方式 Key Generator

    然而當前的這么多種生成方式未必能滿足我們的要求.
    比如increment,可以在一個hibernate實例的應用上很方便的時候,但是在集群的時候就不行了.
    再如 identity ,sequence ,native 是數據局提供的主鍵生成方式,往往也不是我們需要,而且在程序跨數據庫方面也體現出不足.
    還有基于算法的生成方式生成出來的主鍵基本都是字符串的.

    我們現在需要一種生成方式:使用Long作為主鍵類型,自動增,支持集群.
    那么我們需要自定義一個我們的主鍵生成器才能實現了.

    實現代碼:
    package hibernate;

    import java.io.Serializable;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Properties;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.hibernate.HibernateException;
    import org.hibernate.MappingException;
    import org.hibernate.dialect.Dialect;
    import org.hibernate.engine.SessionImplementor;
    import org.hibernate.id.Configurable;
    import org.hibernate.id.IdentifierGenerator;
    import org.hibernate.id.PersistentIdentifierGenerator;
    import org.hibernate.type.Type;


    public class IncrementGenerator implements IdentifierGenerator, Configurable {
        
    private static final Log log = LogFactory.getLog(IncrementGenerator.class);
        
    private Long next;
        
    private String sql;
        
    public Serializable generate(SessionImplementor session, Object object)
                
    throws HibernateException {
            
    if (sql!=null{
                getNext( session.connection() );
            }

           
    return next;

        }

        
        
    public void configure(Type type, Properties params, Dialect d) throws MappingException {
            String table 
    = params.getProperty("table");
            
    if (table==null) table = params.getProperty(PersistentIdentifierGenerator.TABLE);
            String column 
    = params.getProperty("column");
            
    if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
            String schema 
    = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
            sql 
    = "select max("+column +") from " + ( schema==null ? table : schema + '.' + table );
            log.info(sql);
        }

        
         
    private void getNext(Connection conn) throws HibernateException {
                
    try {
                    PreparedStatement st 
    = conn.prepareStatement(sql);
                    ResultSet rs 
    = st.executeQuery();
                    
    if ( rs.next() ) {
                        next 
    = rs.getLong(1+ 1;
                    }

                    
    else {
                        next 
    = 1l;
                    }

                }
    catch(SQLException e)
                
    {
                    
    throw new HibernateException(e);
                }

                
    finally {
                    
    try{
                    conn.close();
                    }
    catch(SQLException e)
                    
    {
                        
    throw new HibernateException(e);
                    }

                }

            }

    }



    配置:
    在對應的hbm文件里面將id的配置如下:
            <id name="id" type="long" column="id" >
                
    <generator class="hibernate.IncrementGenerator" /> 
            
    </id>

    ps:此生成方式僅通過兩個hibernate實例測試,如發現有問題,請留言.


    Let life be beautiful like summer flowers and death like autumn leaves.

    posted on 2008-09-02 11:59 Alexwan 閱讀(3925) 評論(8)  編輯  收藏 所屬分類: J2EE數據庫

    評論

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 13:25 隔葉黃鶯

    如果當前某個表的ID值是2,某一個實例用這個自定義主鍵生成器得到主鍵是3,但還未插入記錄,這時另一Hibernate實例拿到的主鍵也是3,并執行完 insert 操作后,第一個實例執行 insert 操作。

    像這種情況不知如何保證主鍵的唯一性

    我覺得直接用數據庫來產生主鍵是能保證唯一性的,如果自己程序在有 Hibernate 多實例時確保產生的主鍵唯,也須要加上同步,是否可以把這個同步放到數據庫這一層去,讓程序更簡單。  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 14:23 Alexwan

    說的很有道理.

    另外一個問題凸顯出來了,就是hibernate是在插入數據前去獲取主鍵的,如果是這樣無論用什么辦法去做都是有機會導致主鍵不唯一啊(多hibernate實例的情況下),只是視乎幾率的大小而已.

    如果將生成主鍵的工作放到數據庫這一層,那么在插入之前hibernate是不知道主鍵是多少的,這樣的話,我又如何去獲取我剛剛插入那條數據呢?有的時候需要返回新的記錄對象.  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 14:32 隔葉黃鶯

    看看 Hibernate 的 session.save() 操作,它返回的就是一個主鍵,從源代碼就知道,它是首先取得主鍵,然后再 insert ........
    而不是通常像我們那樣(比如說在 Oracle)insert into ...... values(oneSeq.nextval.....  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 15:45 Alexwan

    剛用這個主鍵生成配置后,用兩臺機器各自運行一個hibernate的實例,同時往一個數據表不停的插數據,數據量各為1萬,未出現主鍵不唯一的情況.

    可以放心使用了!  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 16:06 隔葉黃鶯

    測試代碼中業務邏輯要體現出來,比如兩個長短不一樣的邏輯(通常是有的,針對用戶的輸入可能復雜度不一樣的),長邏輯的實例先拿到主鍵(2),這時短邏輯的實例進來也拿到主鍵(2),然后很快 insert 了記錄,而長邏輯的實例之后才執行 insert,這種情況也就出問題了。

    再者,把 Hibernate 實例換成了多線程環境中的線程,即使不是在集群環境下也是會出問題的。  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 16:59 Alexwan

    從事務的角度來看確實會有問題.

    那這樣的話,您認為如果要在集群的環境下保持主鍵唯一,使用什么方式要一點呢?有沒有這方面的經驗呢?  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 17:20 隔葉黃鶯

    當然還是數據庫,產生主鍵的機制設置為 Native,數據庫方言也會選擇正確的數據庫對象來產生主鍵,如 Oracle 的序列,Db2 的 indentity,某些數據庫的自增字段。  回復  更多評論   

    # re: [hibernate]hibernate中自定義主鍵生成器 2008-09-02 17:38 Alexwan

    OK,謝謝指教  回復  更多評論   

    主站蜘蛛池模板: 99免费在线视频| 亚洲人成免费电影| 91在线视频免费91| 亚洲色偷拍区另类无码专区| 亚洲午夜视频在线观看| 日本亚洲中午字幕乱码| 免费观看成人久久网免费观看| 性色av免费观看| 亚洲国产精品无码久久一区二区 | 黄色免费在线网站| 日韩一区二区a片免费观看| 亚洲欭美日韩颜射在线二| 中国china体内裑精亚洲日本| 99re6在线视频精品免费| 精品国产精品久久一区免费式| 久久亚洲国产中v天仙www| 亚洲av日韩综合一区久热| 日韩免费无码一区二区三区| 亚洲国产av一区二区三区| 亚洲国产精品日韩在线观看| 久久国产精品免费| 免费被黄网站在观看| 亚洲精选在线观看| 一级大黄美女免费播放| 丁香花在线观看免费观看| 亚洲av无码国产精品夜色午夜| 国产成人 亚洲欧洲| 91免费国产在线观看| 国产亚洲综合网曝门系列| 美女黄色毛片免费看| 国产va免费精品观看精品| 亚洲第一区香蕉_国产a| 一个人免费观看日本www视频| 在线播放免费播放av片| 亚洲成在人线电影天堂色| 国产高清不卡免费视频| 亚洲国产精品无码久久青草| 亚洲免费网站观看视频| 免费在线观看h片| 亚洲成人在线网站| 国产色无码精品视频免费|