關於iBatis-selectKey的一點筆記


技術前提:我們使用iBatis作為持久層方案 

技術場景: 
    假設我們有兩張表,一張主表Main,一張子表Sub,並且主表的主鍵是由數據庫維護的自增長的主鍵,子表中有一個字段引用這個主鍵,那么當我們插入主表數據后,就需要馬上返回這個自增長的主鍵。 

解決方案: 
    可以在insert時通過iBatis的selectKey返回那個主鍵。 
    selectKey有3個主要的屬性: 
    1)resultClass:返回的主鍵的數據類型,跟sqlMap中的數據類型一致; 
    2)type:表示主鍵在insert之前或之后生成(取決於數據庫的主鍵生成策略),取值分別為[pre|post],非必須,未填寫時如果在insert之前表示pre,否則表示post; 
    2)keyProperty:返回值保存到的屬性,非必須(作用參見Oracle配置); 

實際配置: 
<!-- Oracle SEQUENCE -->    
<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">    
    <selectKey resultClass="int" keyProperty="id" type="pre">    
        <![CDATA[ 
          SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL 
        ]]>    
    </selectKey>    
    <![CDATA[ 
    insert into PRODUCT(PRD_ID,PRD_DESCRIPTION) values(#id#,#description#) 
<!-- 此處體現了keyProperty的作用 -->  
    ]]>    
</insert>  

<!-- Microsoft SQL Server IDENTITY Column -->    
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">    
    <![CDATA[ 
      insert into PRODUCT (PRD_DESCRIPTION) values(#description#) 
    ]]>    
    <selectKey resultClass="int" keyProperty="id" type="post">    
        <![CDATA[ 
          SELECT @@IDENTITY AS ID 
        ]]>  
        <!-- 該方法不安全 應當用SCOPE_IDENTITY() 但這個函數屬於域函數,需要在一個語句塊中執行。 -->  
    </selectKey>    
</insert>  
上述MS SQL Server配置隨是官網提供的配置,但實際上卻恰恰隱患重重!按下述配置,確保獲得有效主鍵。 

<!-- Microsoft SQL Server IDENTITY Column improvement-->    
<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">    
    <selectKey resultClass="int" keyProperty="id">    
      <![CDATA[ 
        insert into PRODUCT (PRD_DESCRIPTION) values(#description#)  
        SELECT SCOPE_IDENTITY() AS ID 
      ]]>  
    </selectKey>    
</insert>  

<!-- MySQL Last Insert Id -->  
<insert id="insertProduct-Mysql" parameterClass="com.domain.Product">  
    insert into PRODUCT(PRD_DESCRIPTION) values(#description#)    
    <selectKey resultClass="int" keyProperty="id">  
        SELECT LAST_INSERT_ID() AS ID 
    </selectKey>  
</insert> 
<!-- 該方法LAST_INSERT_ID()與數據庫連接綁定,同屬統一會話級別,不會發生上述MS SQL Server的函數問題。 -->  

<!-- DB2 Identity Val Local -->  
<insert id="insertProduct-DB2" parameterClass="com.domain.Product"> 
    insert into PRODUCT(PRD_DESCRIPTION) values(#description#) 
    <selectKey resultClass="int" type="post"> 
        VALUES IDENTITY_VAL_LOCAL() 
    </selectKey> 
</insert> 

<!-- Sqlite sqlite_sequence -->  
<insert id="insertProduct-Sqlite" parameterClass="com.domain.Product"> 
    insert into PRODUCT(PRD_DESCRIPTION) values(#description#) 
    <selectKey resultClass="string" type="post"> 
        SELECT seq FROM sqlite_sequence WHERE name = 'PRD_DESCRIPTION' 
    </selectKey> 
</insert> 
<!-- 主鍵字段一定要加下INTEGER PRIMARY KEY AUTOINCREMENT,否則會報找不到 sqlite_sequence 表。 --> 


通過以上方式,可以最大程度上確保插入數據的時候獲得當前自增主鍵。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM