最近在开发一个可持续集成平台devops,在开发时涉及到了批量操作,关键是数据库还都是多张表关联的,由于以前对这方面接触比较少,所以还是感觉比较困难的。经过几天的学习和实践,最终还是成功实现了。代码还未优化,所以有些粗糙,先写篇博客记录下,后续会进行代码的优化。
为什么要执行批量操作
MyBatis操作数据库时经常会出现批量操作,例如:批量新增,批量修改,批量删除。批量操作要比数据循环执行的效率要高很多,特别是当需要操作的数据量特别大的情况下。循环执行每次都需要跟数据库建立一个连接,当连接数达到连接池上限时,系统会直接瘫痪。所以循环执行操作数据库尽量不要采用。
foreach标签
foreach主要是用在构建in条件中,它主要是在SQL语句中进行循环迭代一个集合。
foreach标签的主要属性有collection、index、item、separator、open、close。
collection最容易出错,该属性在使用前必须先指定。根据传过来的参数,一般可以有三种类型(list、array、map)。
index指定一个名字,用于在迭代的过程中迭代到的位置。
item表示集合中每一个元素进行迭代时的别名。
separator指定在迭代时以什么符号作为分隔符。
open、close表示语句以什么开始,以什么结束。
多表关联
mybatis关于多表关联有相应的处理办法,提供了association和collection两个标签。
association通常是用来对应一对一的关系。
collection通常是用来对应一对多关系或者是多对多的关系。
但是因为项目是前后端分离,公司自己封装了框架,对复杂类型的数据不太友好,加上项目数据量也不算太大,所以没有使用这两个标签,而是直接新建一个实体类包含两张表里面的共同数据,然后在mapper中映射到创建的实体即可。
批量增加
在添加的过程中,其它的字段都相同,但是可以输入多个IP,有多少个IP,就在数据库中添加多少条数据实现批量新增。在项目中,前台传给后台一个对象AppInfoFilter,因为有部分字段需要转换,所以需要将字段转换后封装到集合然后返回前台。核心代码如下:
数据的转换
先将前台传过来的数据进行转换,然后将多个IP进行拆分,将所有字段封装到一个新的对象,最后将这个对象封装成集合传到mapper中进行批量增加。
1 | @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) |
代码未进行优化,所以看起来有点乱。由于是三张表关联,所以分别想三张表中插入数据(找了好久资料也想了很久也没实现一条SQL实现三张表插入)。
将集合中的数据插入到数据库中
执行单表批量增加的SQL语句:
1 | <insert id="batchInsert" parameterType="java.util.List"> |
对于单表来说,批量增加还是比较简单的。但是这样非常消耗连接池资源。长久肯定是不可能的。
批量修改
由于项目中此模块涉及到的字段太多,但是客户要求只有几个字段能够修改,其它字段全部设为不可修改状态,所以批量修改还是比较轻松的。类似于批量增加,还是先将要批量修改的对象封装成集合。
数据的封装
AppUpdateInfo 实体中只有四个字段,,替换掉AppInfo中的旧数据,将AppInfo封装成一个集合,然后利用SQL语句进行多表关联修改即可。
1 | //批量修改 |
将数据库中的数据进行修改
先将几张表进行关联,然后进行批量更新。
1 | <update id="batchUpdate" parameterType="java.util.List"> |
批量删除
批量删除根据传入的多个uuid进行删除,只需要在SQL中将多张表关联,然后用foreach遍历封装了uuid的list集合进行删除即可。
核心代码如下:
1 | <delete id="batchDelete" parameterType="java.util.List"> |
技术太low,代码写的很差,很多地方都可以优化,而且有些控制都没有加上。但是写这份代码对我的帮助挺大的,对mybatis的使用熟悉了很多。虽然这是我做的第二个项目,但是却走了整个的流程。学到的东西挺多的。