程序猿的日常——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);
		}
	}
}
posted @ 2018-03-07 18:28  xingoo  阅读(570)  评论(0编辑  收藏  举报