程序猿的日常——Mybatis现学现卖
最近有一个小项目需求,需要用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
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
然后再对应的代码上直接加上注解就行了:
@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 id="saveB" parameterType="map" useGeneratedKeys="true" keyProperty="b.id">
insert into process( content) values (#{b.content})
</insert>
对应的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);
}
}
}