这几天项目中有这样的需要,有一批数据需要进行批处理,并且有些数据数据表中已经存在。这种数据修改或添加自然想到了oracle数据库的函数merge;而且要实现批处理,因为使用的事ibatis所以想到用iterate(高版本的mybatis可以是用foreach,没有进行测试。同学们可以自己试试)。
下面是代码,亲测没有问题:
<update id="test" parameterClass="map">
merge into table a
using
<dynamic>
(select * from
(<iterate open="" close="" conjunction=" union " property="list">
select #list[].a# a, #list[].b# b, #list[].c# c from dual
</iterate>))
</dynamic> b
on (a.a= b.a)
when not matched then --如果在新的伪表中找不到与旧表的关联执行insert
insert (a.a, a.b, a.c) --如果旧表的字段和伪表的字段完全一样,则可以省去制定列
values (b.a, b.b, b.c)
when matched then --如果找到关联进行update
update set a.b=b.b, a.c=b.c -- 切记这里不要写关联字段,因为关联字段已经进行判断,这里不需要修改
</update>
其中property中的list为传入的参数map中定义的集合名称。传入的list集合数据如下:
//测试集合数据
List<ObjectA> list = new ArrayList<ObjectA>();
ObjectA o1 = new ObjectA();
o1.setA("a");
o1.setA("b");
o1.setA("c");
list.add(o1);
ObjectA o2 = new ObjectA();
o2.setA("a");
o2.setA("b");
o2.setA("c");
list.add(o2);
以上为在ibatis基础上使用iterate实现动态拼接merge函数的过程。其中最需要注意的事merge中伪表的使用。如果merge函数不太熟悉可以google一下这个函数,非常好用。而且这样做批处理还可以省去原子性事物的判断。这个语句如果有一条数据插入失败则会全部回滚。