zoukankan      html  css  js  c++  java
  • ibatis selectKey

    复制代码
    <insert id="insert" parameterClass="A">  
           <selectKey keyProperty="uuid" type="pre">  
               select seq_sample.nextval from dual  
           </selectKey>  
           <![CDATA[  
            insert into tbl_sample(uuid,name) values (#uuid#,#name#)  
           ]]>  
    </insert>  
    复制代码

    加上type="pre"(表示在执行insert之前获取主键)

    后台输出sql

    在log4j.properties中配置 
    log4j.logger.java.sql=DEBUG,console

    今天在用ibatis selectKey 生成 oracle sequence 的时候 发现一个问题。
    其实就是相为SHIPMENT_HISTORY表加入一个主键sequence id shipmentHistoryId,加入一条记录,然后返回这个sequence id

    xml 代码

    复制代码
    <insert id="abatorgenerated_insert" parameterClass="cn.hot.delivery.domain.ShipHistory">
        insert into SHIPMENT_HISTORY (SHIPMENT_ID, RECORD_CREATED_DATE, REMARK)  
        values (#shipmentId:DECIMAL#,  #recordCreatedDate:DATE#, #remark:VARCHAR#)  
        <selectKey keyProperty="shipmentHistoryId" resultClass="java.math.BigDecimal">
          select SHIPMENT_HISTORY_ID_SEQUENCE.nextVal from dual  
        <selectKey>
    <insert>
    复制代码

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

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

    xml 代码

    复制代码
    < !—Oracle SEQUENCE Example -->
    <insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">
       <selectKey resultClass="int" keyProperty="id" >
         SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL   
    <selectKey>
       insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)   
       values (#id#,#description#)   
    <insert>
     
    <insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">
        insert into PRODUCT (PRD_DESCRIPTION)   
        values (#description#)   
        <selectKey resultClass="int" keyProperty="id" >
          SELECT @@IDENTITY AS ID   
    <selectKey>
    <insert>
    复制代码

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

    xml 代码

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

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

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

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

    xml 代码

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

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

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

    同时得到newKey这个sequence

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

  • 相关阅读:
    2、细节&Class对象
    1、概述&应用场景
    Magento请求分发与控制器
    Magento强大的配置系统
    ecshop在PHP 5.4以上版本各种错误问题处理
    Thinkphp单字母函数使用指南
    五种常见的 PHP 设计模式
    MyISAM和InnoDB的区别
    linux下如何删除文件夹
    Linux软件安装与卸载
  • 原文地址:https://www.cnblogs.com/shaohz2014/p/3791031.html
Copyright © 2011-2022 走看看