`
hotforcc
  • 浏览: 60546 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ibatis selectKey用法问题

阅读更多
今天在用ibatis selectKey 生成 oracle sequence 的时候 发现一个问题。

其实就是相为SHIPMENT_HISTORY表加入一个主键sequence id shipmentHistoryId,加入一条记录,然后返回这个sequence id

xml 代码
 
  1. <insert id="abatorgenerated_insert" parameterClass="cn.hot.delivery.domain.ShipHistory">  
  2.      insert into SHIPMENT_HISTORY (SHIPMENT_ID, RECORD_CREATED_DATE, REMARK)  
  3.     values (#shipmentId:DECIMAL#,  #recordCreatedDate:DATE#, #remark:VARCHAR#)  
  4.     <selectKey keyProperty="shipmentHistoryId" resultClass="java.math.BigDecimal">  
  5.       select SHIPMENT_HISTORY_ID_SEQUENCE.nextVal from dual  
  6.     <<!---->selectKey>  
  7.  <<!---->insert>  

并且这段statement是由Abator自动生成的,蛮以为肯定不会出错的 。  但是这个 statement在运行的时候报错了 ,说不能插入 能null数值插入到SHIPMENT_HISTORY表中 ,说明这个selectKey就根本没有发挥出作用 。

查找了一下ibatis的中文文档 ,上面由下面的说明如下 :

很多数据库支持自动生成主键的数据类型。不过这通常(并不总是)是个私有的特性。SQL Map通过<insert></insert>的子元素<selectkey></selectkey>来支持自动生成的键值。它同时支持预生成(如Oracle)和后生成两种类型(如MS-SQL Server)。下面是两个例子:

xml 代码
  1. < !—Oracle SEQUENCE Example -->   
  2. <insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">   
  3.    <selectKey resultClass="int" keyProperty="id" >   
  4.      SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL   
  5.    <!----><selectKey>   
  6.    insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)   
  7.    values (#id#,#description#)   
  8. <insert>   
  9. <!---->
  10. <insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">   
  11.     insert into PRODUCT (PRD_DESCRIPTION)   
  12.     values (#description#)   
  13.     <selectKey resultClass="int" keyProperty="id" >   
  14.       SELECT @@IDENTITY AS ID   
  15.     <<!---->selectKey>   
  16. <insert>   


也就是说对于oracle来说,<selectKey>   statement是必须前置的,并且 必须把sequence id放到insert into 句子中,就会没有问题的。按照上面的更改我自己的xml如下,果然没有问题了

 

xml 代码
 
  1. <insert id="abatorgenerated_insert" parameterClass="cn.hot.delivery.domain.ShipHistory">    
  2.      <selectKey keyProperty="shipmentHistoryId" resultClass="java.math.BigDecimal">    
  3.            select SHIPMENT_HISTORY_ID_SEQUENCE.nextVal as value  from dual    
  4.      <!----><selectKey>    
  5.    insert into SHIPMENT_HISTORY (SHIPMENT_HESTORY_ID,SHIPMENT_ID, RECORD_CREATED_DATE, REMARK)      value(#shipmentHistoryId:DECIMAL#,#shipmentId:DECIMAL#, #recordCreatedDate:DATE#, #remark:VARCHAR#)    
  6. <insert>    

所以对于不同的数据库来说 。<!---->selectKey>   的用法可能是不一样的,网上的由很多资料的解释是根据不同的数据库的驱动,然后<!---->selectKey>   的用法也不一样。但是即使你用Abator来是生成,并且在Abator的配置文件中的

<jdbcconnection driverclass="oracle.jdbc.driver.OracleDriver"></jdbcconnection>

表示这个一个OracleDriver的驱动,但是Abator不会的根据不同的驱动然后生成不同的<!---->selectKey> 语句,所以说你如果用到oracle的时候,只能手工的改动这个statement了。


其实也可以用在insert语句中直接调用SEQUENCE.nextVal的方法来生成sequence id,例如

xml 代码
  1. <insert id="abatorgenerated_insert" parameterClass="cn.hot.delivery.domain.ShipHistory">  
  2. insert into SHIPMENT_HISTORY (SHIPMENT_HISTORY_ID,SHIPMENT_ID,RECORD_CREATED_DATE, REMARK)  
  3. Values  
  4. (SHIPMENT_HISTORY_ID_SEQUENCE.nextVal,#shipmentId:DECIMAL#, #recordCreatedDate:DATE#, #remark:VARCHAR#)  
  5. <insert>  

这个statement是可以生成sequence并且插入记录的,唯一的缺点就是你不能同时通过

Object newKey = getSqlMapClientTemplate().insert(
"SHIPMENT_HISTORY.abatorgenerated_insert", record);

同时得到newKey这个sequence

总之,相对来说,<!---->selectKey>还是比较好用的,只要你注意你用的数据库的问题(再说,ibatis也没有屏蔽掉数据库之间的差异)

<o:p></o:p>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics