程序猿的日常——Mybatis现学现卖

时间:2022-05-06
本文章向大家介绍程序猿的日常——Mybatis现学现卖,主要内容包括1 spring mvc + mybatis的事务、2 一次性删除多张表的数据、3 插入后直接返回主键、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

最近有一个小项目需求,需要用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);
        }
    }
}