前兩篇手記重點說了下iBATIS 3的查詢功能,因爲這是它改動最大的地方。這篇手記就來說下iBATIS在Persistance方面的改進。
iBATIS 3依然提供了<insert><update><delete>標籤對數據庫進行持久化操作。首先來看insert操作:
<insert id="insertNewsNotice" parameterType="org.newsnotice.domain.NewsNoticeModel" flushCache="true"
statementType="PREPARED" timeout="20000">
<selectKey keyProperty="nnId" order="BEFORE" resultType="long">
SELECT SEQ_NN_MSTR_ID.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO NN_MSTR(
NN_ID
<if test="category != null">,CATEGORY</if>
<if test="subject != null">,SUBJECT</if>
,POSTED_DATE
,EXPIRY_DATE
<if test="alert != null">,ALERT</if>
<if test="emailAlert != null">,EMAIL_ALERT</if>
<if test="audience != null">,AUDIENCE</if>
<if test="filter != null">,FILTER</if>
<if test="filterValue != null">,FILTER_VALUE</if>
<if test="subFilterValue != null">
,SUB_FILTER_VALUE
</if>
<if test="excludeUserId != null">
,EXCLUDE_USER_ID
</if>
<if test="department != null">,WF_DEPARTMENT</if>
<if test="status != null">,WF_STATUS</if>
<if test="notes != null">,WF_NOTES</if>
<if test="createdBy != null">,WF_CREATED_BY</if>
<if test="createdDate != null">,WF_CREATED_ON</if>
<if test="modifiedBy != null">,WF_MODIFIED_BY</if>
<if test="modifiedDate != null">
,WF_MODIFIED_ON
</if>
<if test="approvedBy != null">,WF_APPROVED_BY</if>
<if test="approvedOn != null">,WF_APPROVED_ON</if>
<if test="version != null">,WF_VERSION</if>
)VALUES(
#{nnId}
<if test="category != null">,#{category}</if>
<if test="subject != null">,#{subject}</if>
,sysdate
,sysdate + 7
<if test="alert != null">,#{alert}</if>
<if test="emailAlert != null">,#{emailAlert}</if>
<if test="audience != null">,#{audience}</if>
<if test="filter != null">,#{filter}</if>
<if test="filterValue != null">,#{filterValue}</if>
<if test="subFilterValue != null">
,#{subFilterValue}
</if>
<if test="excludeUserId != null">
,#{excludeUserId}
</if>
<if test="department != null">,#{department}</if>
<if test="status != null">,#{status}</if>
<if test="notes != null">,#{notes}</if>
<if test="createdBy != null">,#{createdBy}</if>
<if test="createdDate != null">,#{createdDate}</if>
<if test="modifiedBy != null">,#{modifiedBy}</if>
<if test="modifiedDate != null">
,#{modifiedDate}
</if>
<if test="approvedBy != null">,#{approvedBy}</if>
<if test="approvedOn != null">,#{approvedOn}</if>
)
</insert>
對於<insert>,iBATIS 3新增了以下屬性:
- useGeneratedKeys:當設置爲true時,它會自動從表的自增列獲取主鍵值,像MySQL/MS SQL Server都提供了此類型的主鍵
- keyProperty:存儲主鍵的屬性名
- statementType:可以設置爲STATEMENT,PREPARED,CALLABLE,默認爲PREPARED,像在調用存儲過程時就可以使用CALLABLE類型
另外一個改進是在insert時支持使用<selectKey>標籤獲取主鍵值,如上面代碼所示。keyProperty指定存放主鍵的屬性名,order指定<selectKey>的執行順序,值可以爲BEFORE或AFTER,如果是BEFORE則先執行<selectKey>中的SQL,再執行<insert>操作,AFTER則相反。
接下來是update操作,iBATIS 3提供了<set>標籤來方便<update>操作,它會自動判斷是否需要加上SET關鍵字。
<update id="updateNewsNotice" parameterType="org.newsnotice.domain.NewsNoticeModel" flushCache="true" statementType="PREPARED" timeout="20000"> UPDATE NN_MSTR <set> <if test="category != null">CATEGORY = #{category},</if> <if test="subject != null">SUBJECT = #{subject}</if> </set> WHERE NN_ID = #{nnId} </update>
至於Delete操作和iBATIS 2相同,在些就不詳述了。
此外再介紹兩個比較有用的標籤:<sql>和<foreach>
<sql>標籤主要用於定義可以重用的SQL,然後在需要用到的地方使用標籤<include>將其加入即可。如下:
<sql id="newsNoticeColumns"> A.NN_ID, A.CATEGORY, A.SUBJECT, A.POSTED_DATE, A.EXPIRY_DATE, A.ALERT, A.EMAIL_ALERT, A.AUDIENCE, A.FILTER, A.FILTER_VALUE, A.SUB_FILTER_VALUE, A.EXCLUDE_USER_ID, A.WF_DEPARTMENT, A.WF_STATUS, A.WF_NOTES, A.DEFUNCT_IND, A.APPROVER, B.ID CONTENT_ID, B.PARENT_NN_ID, B.CONTENT, C.ID MSG_BOX_ID, C.USER_ID, C.NN_ID MSG_BOX_NN_ID, C.FOLDER, C.READ, C.READ_ON, C.DEFUNCT_IND MSG_BOX_DEFUNCT_IND, C.PI_NO MSG_BOX_PI_NO </sql>
<select id="getNewsNotice1" parameterType="org.newsnotice.domain.NewsNoticeModel" resultMap="resultMap-getNewsNotice1" >
SELECT <include refid="newsNoticeColumns"/>
FROM NN_MSTR A, NN_CONTENT B, NN_MSG_BOX C
WHERE A.NN_ID = B.PARENT_NN_ID
AND A.NN_ID = C.NN_ID
......
而<foreach>標籤則用於迭代集合或數組,常用於在IN操作中,其操作類似JSTL中的<c:foreach>,如下:
<select id="foreachSelect" parameterType="org.newsnotice.domain.NewsNoticeModel" resultType="int"> SELECT COUNT(*) FROM NN_MSTR WHERE WF_STATUS IN <foreach collection="statusArray" item="item" index="index" open="(" separator="," close=")"> #{item} </foreach> </select>
最終生成的SQL將是:......WF_STATUS IN (value1, value2, ....)
最後一點需要注意的是如果TransactionType設置JDBC的話,iBATIS 3默認Auto Commit爲false, 所以在執行完持久化操作後,需要調用session.commit()方法來提交事務,或是首先調用session.getConnection().setAutoCommit(autoCommit)來設置Auto Commit策略。
iBATIS 3持久化的介紹就到此,下一篇手記將簡要介紹下iBATIS 3提供的Annotation操作,Annotation在一些簡單SQL應用方面還不非常不錯的,效率高,不用專門去定義xml。