<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,謝謝指教  回復  更多評論   

    主站蜘蛛池模板: 亚洲日韩精品无码专区网址| 亚洲国产精品第一区二区三区| a级毛片黄免费a级毛片| 免费中文字幕不卡视频| 羞羞网站免费观看| 亚洲Av无码乱码在线观看性色| 男女超爽视频免费播放| 亚洲国产精品日韩专区AV| 深夜福利在线视频免费| 伊伊人成亚洲综合人网7777| a视频在线观看免费| 亚洲AV无码成人精品区天堂| 无码日韩精品一区二区三区免费| 久久久久久亚洲av成人无码国产| 国产成人免费AV在线播放| 久久夜色精品国产噜噜噜亚洲AV | 女人毛片a级大学毛片免费| 亚洲人xxx日本人18| 国产午夜精品理论片免费观看 | 人妻视频一区二区三区免费| 亚洲中文字幕一二三四区苍井空| 午夜免费福利影院| 高潮内射免费看片| 久久久亚洲精品国产| h在线观看视频免费网站| 亚洲国产精品无码久久98| 久久亚洲2019中文字幕| 久久国产精品成人免费| 亚洲国产精品成人精品小说| 成人免费视频观看无遮挡| 日本中文字幕免费看| 91天堂素人精品系列全集亚洲| 免费看的成人yellow视频| 最新国产乱人伦偷精品免费网站 | 成年丰满熟妇午夜免费视频| 久久精品成人免费观看97| 精品亚洲国产成AV人片传媒| 卡1卡2卡3卡4卡5免费视频| 中国在线观看免费的www| ASS亚洲熟妇毛茸茸PICS| 亚洲人成无码网WWW|