iBatis批处理有关问题——对Oracle的insert into .select.的异常使用

iBatis批处理问题——对Oracle的insert into ...select...的错误使用

最早发表时间:2009-02-17

 

    在开发一个需要用到iBatis批处理大量数据的功能时,遇到了一个无法优化的问题,苦苦思考了很久,查了很多资料,最终发现是语句没有预编译,导致批处理过程失效。
    在网上看到一些老文章说iBatis早先的版本不适用于批处理于多表的增删改操作,是因为老的iBatis底层对预编译的支持有些问题(这里不赘述,网文丰富得很)。
    该功能描述如下:
    我们需要将一个字段颇多的表(假定名为test_src)中的大量数据转移到另一个结构一样但名称不同的目标表(假定名为test_dest)中,使用insert ... select ...时,语句是这样写:

    insert into test_dest (id, col_B, col_C) 
    select '$newId$', col_B, col_C 
    from test_src s 
    where s.id = #id#

  

    其中参数newId是新纪录的新主键,为了防止与test_dest中已有的老数据重复,id是需要拷贝的旧数据的主键值,但是这里我犯了一个错误,由于对每条数据拷贝动作中'$newId$'都是一个新的值,也就导致了iBatis底层调用的PreparedStatment的预编译特性失效了,因为每次执行的SQL都不一样,而非只是参数不一样。

    为了实现相同的目的,向同事求教,发现我们使用的数据库中Oracle已经包含了一个生成UUID的函数,sys_uuid(),语句最终改成:

    insert into test_dest (id, col_B, col_C) 
    select sys_uuid(), col_B, col_C 
    from test_src s 
    where s.id = #id#

  

    这样只有参数部分是变动的,语句部分没有变化,预编译特性可以用上了!