最近有一个小项目需求,需要用spring mvc + mybatis实现一个复杂的配置系统。其中遇到了很多不太常见的问题,在这里特意记录下:

主要涉及的内容有

事务

多表删除

插入并返回主键

1 spring mvc + mybatis的事务

背景

大概就是有ABC三张表,A表跟B表是一对多关系,B表跟C表是一对多关系。在创建的时候提交了一个大的json,需要先暴力删除A中某行关联的所有B和所有C,然后分别创建B,再创建C。这些操作要在一个事务中进行,不能删完,插入失败。

结构长得如下:

{

"id":"A1",

"b_arr":[{

"content":"b_123"

"c_arr":[{

"content":"c_123"

},{

"content":"c_456"

}

]

},{

"content":"b_456"

"c_arr":[{

"content":"c_789"

},{

"content":"c_101"

}

]

}

]

}

解决的办法就是直接用spring+mybatis的事务管理,配置如下:

applicationContext.xml

然后再对应的代码上直接加上注解就行了:

@Transactional

public void test(){

// todo 操作1

// todo 操作2

// todo 操作3

}

只有三个操作都顺利完成,才一次性commit

2 一次性删除多张表的数据

背景

同上,想要在更新其中某个内容的时候,直接删除所有相关的B表数据和C表数据,为了节省时间,就放在一个sql中操作了。

delete b,c from a

left join b on a.id = b.a_id

left join c on b.id = c.b_id

where a.id = #{id}

这样就可以根据A的一个id,同时删除B表和C表的数据了。

3 插入后直接返回主键

背景

还是上面的问题,大json中包含所有的内容,可以看到如果B表和C表的Id都是自增的。但是C表中有一个B表的外键,如果想要自动插入C表,就必须先获的B表对应的主键。

总结来说,就是需要插入一条数据后,获得其自增长的主键id。

方法采用了mybatis的useGeneratedKeys,即在mybatis的mapper配置文件中:

insert into process( content) values (#{b.content})

对应的interface是:

public void saveB(@Param(value="b") B b);

然后再service层就可以这么用了:

@Transactional

public void test(){

...

for(B b:A.b_arr){

testMapper.saveB(b);

// 注意id是直接保存在b对象中了,而不是返回值!!!

// 注意id是直接保存在b对象中了,而不是返回值!!!

// 注意id是直接保存在b对象中了,而不是返回值!!!

Integer b_id = b.getId();

....

for(C c:b.c_arr){

c.setBId(b_id);

testMapper.saveC(c);

}

}

}

查看原文