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#
??
??? 这样只有参数部分是变动的,语句部分没有变化,预编译特性可以用上了!