广告
返回顶部
首页 > 资讯 > 精选 >如何使用Mybatis的Batch Insert Support实现批量插入
  • 196
分享到

如何使用Mybatis的Batch Insert Support实现批量插入

2023-07-02 16:07:19 196人浏览 泡泡鱼
摘要

这篇文章主要介绍了如何使用mybatis的Batch Insert Support实现批量插入的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用Mybatis的Batch In

这篇文章主要介绍了如何使用mybatis的Batch Insert Support实现批量插入的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用Mybatis的Batch Insert Support实现批量插入文章都会有所收获,下面我们一起来看看吧。

Batch Insert Support 批量插入

开发中如果遇到需要批量insert的需求,可以使用Mybatis 的 Batch Insert Support 提高插入效率。

代码实例(开发的项目中截取的片段)

@Autowiredprivate sqlSessionTemplate sqlSessionTemplate;public int insertFolder(List<IpsCatalogFolderDetail> ips) {        //获取sql会话        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);        //通过新的session获取mapper,而不是常规的spring管理注入        IipsCatalogFolderDetailDao folderDetailDao = session.getMapper(IipsCatalogFolderDetailDao.class);        int size = ips.size();        //如果有父类子类两层都需要批量插入也可        try {        //外层循环            for (int i = 0; i < size; i++) {                    ips.get(i).setType("folder");                    //用上面在session中获取的mapper进行插入操作                    folderDetailDao.insertFolder(ips.get(i));                //内层循环                String cs = ips.get(i).getContentIds();                if (StringUtils.isNotBlank(cs)){                        List<String> con = JSON.parseArray(cs,String.class);                    if (cs != null && con.size() > 0) {                        for (int j = 0; j < con.size(); j++) {                                IpsCatalogFolderDetail ifd = new IpsCatalogFolderDetail();                                ifd.setParentCode(ips.get(i).getCode());                                ifd.setContentId(con.get(j));                                ifd.setType("contents");                                 //同样用上面在session中获取的mapper进行插入操作                                folderDetailDao.insertFolder(ifd);                        }                    }                }                //最后批量提交                    if (i % 200 == 0 || i == size - 1) {                        session.commit();//200个提交一次,手动提交,提交后无法回滚                        session.clearCache(); //清理缓存,防止溢出                    }            }        }catch (Exception e) {            System.out.println(e.toString());           session.rollback(); //没有提交的数据可以回滚        } finally {            session.close();        }        return 0;    }

另外有时我们在插入的时候需要先查询数据是否已存在,如果也需要批量操作可将insert和update语句合并,然后就可以继续使用Batch Insert了

oracle数据库sql示例

@Insert("merge into ips_catalog_folder_detail fd " +            "using(select #{code,jdbcType=VARCHAR} c from dual)t " +            "on(fd.FOLDERID = t.c)" +                        "when matched then"+            "update set "+            ...(省略)...            "where ..."+            "when not matched then insert(" +            "fd.PROD_LINE," +            "fd.TYPE," +            "fd.PARENTFOLDERCODE," +            "fd.FOLDERID," +            "fd.FOLDERCODE," +            "fd.FOLDERNAME," +            "fd.COLUMN_SORTINDEX," +            "fd.DESCRIPTION," +            "fd.CONTENTID," +            "fd.CREATETIME" +            ")" +            "VALUES" +            "(" +            "#{prod_line}," +            "#{type,jdbcType=VARCHAR}," +            "#{parentCode,jdbcType=VARCHAR}," +            "#{code,jdbcType=VARCHAR}," +            "#{aliasCode,jdbcType=VARCHAR}," +            "#{name,jdbcType=VARCHAR}," +            "#{sortIndex,jdbcType=VARCHAR}," +            "#{desc,jdbcType=VARCHAR}," +            "#{contentId,jdbcType=VARCHAR}," +            "#{createTime,jdbcType=VARCHAR}" +            ")")            int insertFolder(IpsCatalogFolderDetail fd);

MYSQL示例:

REPLACE INTO users (id,name,age) VALUES(1, '张雨绮', 32);

批量插入几千条数据优化(foreach)

项目中有一个耗时较长的Job存在CPU占用过高的问题

经排查发现,主要时间消耗在往MyBatis中批量插入数据。mapper configuration是用foreach循环做的,差不多是这样。

<insert id="batchInsert" parameterType="java.util.List">    insert into USER (id, name) values    <foreach collection="list" item="model" index="index" separator=",">         (#{model.id}, #{model.name})    </foreach></insert>

优化代码

可以看 Http://www.mybatis.org/mybatis-dynamic-sql/docs/insert.html 中 Batch Insert Support 标题里的内容)

SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);try {    SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);    List<SimpleTableRecord> records = getRecordsToInsert(); // not shown     BatchInsert<SimpleTableRecord> batchInsert = insert(records)            .into(simpleTable)            .map(id).toProperty("id")            .map(firstName).toProperty("firstName")            .map(lastName).toProperty("lastName")            .map(birthDate).toProperty("birthDate")            .map(employed).toProperty("employed")            .map(occupation).toProperty("occupation")            .build()            .render(RenderingStrategy.MYBATIS3);     batchInsert.insertStatements().stream().forEach(mapper::insert);    session.commit();} finally {    session.close();}

总结一下,如果MyBatis需要进行批量插入,推荐使用 ExecutorType.BATCH 的插入方式,如果非要使用 <foreach>的插入的话,需要将每次插入的记录控制在 20~50 左右

关于“如何使用Mybatis的Batch Insert Support实现批量插入”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“如何使用Mybatis的Batch Insert Support实现批量插入”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: 如何使用Mybatis的Batch Insert Support实现批量插入

本文链接: https://www.lsjlt.com/news/343157.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作