J Hi 開發日記(二)

2021-12-29 20:50:32 字數 2349 閱讀 4418

張昊

最近在做j-hi融合springjdbc時遇到乙個棘手的問題,那就是在insert一條記錄時如何取回記錄主鍵值的?問題主要讓我糾結在對跨資料庫springjdbc的處理上,大家都知道象sqlserver或myserver主鍵的值是以自增的方式,而象oracle主建的值通過序列生成並通過insert將值直接插入到表中的。為此springjdbc提供了兩種機制,

1、主鍵自增的解決方案

keyholder keyholder = new generatedkeyholder();

this.getjdbctemplate().update(new preparedstatementcreator()

}, 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, "******_sequence");

return incr.nextintvalue();象oracle這樣的資料庫springjdbc的解決方案一目了解,通過給定資料來源datasource與序列名"******_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()

}, 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) sqlserver的方言方法:

public number getselectkey(string entityname, datasource datasource) 通過返回主鍵值是否為null,還判斷在拼寫sql時是否插入主鍵欄位的值

最後通過

if(obj.getprimarykey() == null)

beanutil.setpropertyvalue(obj, "id", keyholder.getkey().intvalue());

pojo物件是否主鍵值(如果沒有就說明是自增型的如sqlserver,如果有就說明是序列生成的如oracle),來將其賦值到pojo的屬性中

android wifi驅動開發日記(二)

由於在這個專案中,wifi模組是採用sdio匯流排來控制的,所以先記錄下client driver的sdio部分的結構,這部分的sdio分為三層 sdiodrv sdioadapter sdiobusdrv。其中sdiobusdrv是client driver中sdio與wifi模組的介面,sdio...

後端開發菜鳥日記 二

每一周都感覺過的很快 第乙個任務就是,自己根據已有的機械人節點,寫乙個自定義的機械人節點,這個任務,邏輯很簡單,就是獲取到頁面中的值,並將值已郵件的形式進行傳送到自定義的人。isysmetadataparser sysmetadataparser isysmetadataparser springb...

QT開發日記

1,在使用moc的時候,q object這個巨集不能用在乙個類的定義檔案中,只能在單獨作為乙個類的宣告檔案中用,否則會出現 vtable for x 類名 的出錯提示。如果乙個類只宣告了,而沒有定義,也會出現上述錯誤.這時可以在這個檔案的末尾加上 include moc xx為不要.cpp字尾的檔名...