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

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

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

    張昊

    J-Hi(http://www.j-hi.net)

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      45 Posts :: 1 Stories :: 110 Comments :: 0 Trackbacks
    最近在做J-Hi融合SpringJDBC時遇到一個棘手的問題,那就是在insert一條記錄時如何取回記錄主鍵值的?問題主要讓我糾結在對跨數據庫SpringJDBC的處理上,大家都知道象SQLServer或MyServer主鍵的值是以自增的方式,而象Oracle主建的值通過序列生成并通過insert將值直接插入到表中的。為此SpringJDBC提供了兩種機制,
        1、主鍵自增的解決方案
            KeyHolder keyHolder = new GeneratedKeyHolder(); 
            
    this.getJdbcTemplate().update(new PreparedStatementCreator(){

                
    public PreparedStatement createPreparedStatement(Connection con)
                        
    throws SQLException {
       
    PreparedStatement ps
    =con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
     
                    
    return ps;
                }
                
            }, keyHolder);
            
        
    return keyHolder.getKey().intValue();
    keyHolder 數據庫自增主鍵值的持有者,它監聽PreparedStatement的返回的值Statement.RETURN_GENERATED_KEYS獲取主鍵值,并存放在自己的池中(實際上是一個list)一般來說,一個keyHolder實例只綁定一個PreparedStatement的執行,當然最好也只是插入一條數據庫記錄,這樣才能保證池中只有一個主鍵值。
    當keyHolder獲得主鍵值后,您可以在任何時候通過訪問keyHolder對象得到這個主鍵值,也就是說只要它的生命期存在,這個主鍵的值就一直不會丟失。
    總結:1)、在執行
    PreparedStatement之前創建自增主鍵的持有者對象keyHolder
          2)、在創建
    PreparedStatement對象時一定要聲明返回主鍵值,列如con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)
          3)、只要keyHolder的生命期存在,那么主鍵的值在任何時候與位置你都可以取得到

        2、檢索數據庫序列生成的主鍵的解決方案
            OracleSequenceMaxValueIncrementer incr = new OracleSequenceMaxValueIncrementer(dataSource, "SIMPLE_SEQUENCE");
            
    return incr.nextIntValue();
    象Oracle這樣的數據庫SpringJDBC的解決方案一目了解,通過給定數據源dataSource與序列名"SIMPLE_SEQUENCE"就可以這個序列的最大值。當然還可以通過這個類設計緩沖區大小通過setCacheSize方法,該方法可以一次性取出多個值以減少與數據庫的訪問次數(數據庫的交互是很耗時與耗費資源的)

    J-Hi的問題與解決方法
        因為J-Hi要實現跨數據庫跨多個ORM框架因此對于SpringJDBC這兩種方案必須要融合到一起,并且在總體設計上還要與其它的ORM框架(目前J-Hi已融合的ORM框架有hibernate、ibatis2、ibatis3)的接口聲明相兼容,因此在對SpringJDBC集成的總體設計上我借鑒了hibernate的方言思想,通過方言將SpringJDBC兩種方案融合在J-Hi之中以實現對不同類型數據庫主鍵管理的差異性。
            KeyHolder keyHolder = new GeneratedKeyHolder(); 
            
    this.getJdbcTemplate().update(new PreparedStatementCreator(){

                
    public PreparedStatement createPreparedStatement(Connection con)
                        
    throws SQLException {
      
    ISpringJDBCHiDialect dialect 
    = sessionFactory.getDialect();   
    PreparedStatement ps
    =con.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
     
                        
    if(stepFlage == primaryKeyIndex && valueClass.getPropertyName().equals(primaryKeyName)){
                            Number _id 
    = dialect.getSelectKey(entity.getEntityName(), getJdbcTemplate().getDataSource());
                    
    return ps;
                }
                
            }, keyHolder);
            
            
    if(obj.getPrimarykey() == null)
                BeanUtil.setPropertyValue(obj, 
    "id", keyHolder.getKey().intValue());

    從原生的SQL語句上講Oracle在insert時要插入主鍵值,而SQLServer恰好相反必須不能插入主鍵的值,我在設計上就是抓住這一特性,再結合方言,實現了跨數據庫的SpringJDBC, dialect.getSelectKey()方法,對應不同的數據庫方言,如果是oracle就會生成主鍵的值,而如果是SQLServer這個方法不會返回任何值,代碼如下
    Oracle的方言方法:
        public Number getSelectKey(String entityName, DataSource dataSource) {
            OracleSequenceMaxValueIncrementer incr 
    = new OracleSequenceMaxValueIncrementer(dataSource, "HIBERNATE_SEQUENCE");
            
    return incr.nextIntValue();
        }
    SQLServer的方言方法:
        public Number getSelectKey(String entityName, DataSource dataSource) {
    //        自增主鍵不用實現該方法
            return null;
        }
    通過返回主鍵值是否為null,還判斷在拼寫sql時是否插入主鍵字段的值
    最后通過
            if(obj.getPrimarykey() == null)
                BeanUtil.setPropertyValue(obj, 
    "id", keyHolder.getKey().intValue());
    Pojo對象是否主鍵值(如果沒有就說明是自增型的如SQLServer,如果有就說明是序列生成的如Oracle),來將其賦值到POJO的屬性中.
    posted on 2011-04-21 00:19 張昊 閱讀(1952) 評論(3)  編輯  收藏

    Feedback

    # re: J-Hi 開發日記(二) 2011-04-21 09:36 playbook
    Good job!  回復  更多評論
      

    # re: J-Hi 開發日記(二) 2011-04-21 15:01 好看的電影
    呵呵,最近也在學這個!  回復  更多評論
      

    # re: J-Hi 開發日記(二) 2011-04-23 21:22 新能源
    寫的詳細呀  回復  更多評論
      


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲天天做日日做天天看| 国产美女视频免费观看的网站| 在线观看免费无码视频| 亚洲成av人片天堂网老年人 | 四虎成人免费观看在线网址| 亚洲ts人妖网站| 日韩国产免费一区二区三区| 亚洲av乱码一区二区三区香蕉 | 中文字幕不卡高清免费| 十八禁的黄污污免费网站| 日本一区免费电影| 亚洲精品午夜无码专区| 99re8这里有精品热视频免费| 亚洲午夜无码久久久久| 久久精品国产大片免费观看| 永久黄网站色视频免费直播| 亚洲精品又粗又大又爽A片| 免费A级毛片无码A| j8又粗又长又硬又爽免费视频| 亚洲gv猛男gv无码男同短文| 亚洲av无码一区二区三区在线播放| 热久久精品免费视频| 久久精品国产亚洲av品善| 亚洲国产精品人人做人人爱| 丝瓜app免费下载网址进入ios| 亚洲综合精品香蕉久久网| 最近免费中文字幕mv电影| 亚洲变态另类一区二区三区 | 三年片在线观看免费| 亚洲精品偷拍视频免费观看| 四虎1515hh永久久免费| 久久久久久久尹人综合网亚洲| 91av免费观看| 日韩国产精品亚洲а∨天堂免| 中国一级全黄的免费观看| 亚洲国产模特在线播放| 亚洲国产成人久久综合一区77| 久久久久成人片免费观看蜜芽| 亚洲视频无码高清在线| 亚洲中文字幕在线乱码| 99久久免费精品国产72精品九九|