zoukankan      html  css  js  c++  java
  • 程序猿的日常——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);
    		}
    	}
    }
    
  • 相关阅读:
    Can't connect to local MySQL server through socket '/tmp/mysql.sock'
    reversePairs
    sort
    分割数组的最小值
    decode string
    276. 栅栏涂色
    133. Clone Graph
    Palindromic string
    爬楼梯
    正则匹配
  • 原文地址:https://www.cnblogs.com/xing901022/p/8524575.html
Copyright © 2011-2022 走看看