返回顶部
首页 > 资讯 > 精选 >MyBatis-plus批量插入的通用方法是什么
  • 939
分享到

MyBatis-plus批量插入的通用方法是什么

2023-07-06 00:07:19 939人浏览 薄情痞子
摘要

这篇文章主要介绍“mybatis-plus批量插入的通用方法是什么”,在日常操作中,相信很多人在MyBatis-plus批量插入的通用方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis-p

这篇文章主要介绍“mybatis-plus批量插入的通用方法是什么”,在日常操作中,相信很多人在MyBatis-plus批量插入的通用方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis-plus批量插入的通用方法是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. MyBatis-plus 的批量保存方法

MyBatis-plus 中默认提供了一个批量保存数据到数据库的方法,也就是 IService#saveBatch() 接口方法。这个方法的实现为 ServiceImpl#saveBatch(),其源码实际处理的关键如下,从中可以知道 IService#saveBatch() 并不是一个真正的批量插入数据的方法

  1. 调用 ServiceImpl#sqlStatement() 使用 SqlMethod.INSERT_ONE 枚举结合实体类确定一个全路径方法名称,这个名称将用于匹配实体对应的库表的单个插入方法的 MappedStatement 对象

  2. 调用 ServiceImpl#executeBatch() 方法遍历 Entity 的集合,使用单个插入的方法为每个实体组装一个 INSERT INTO 语句,遍历结束后 flush,一次性将所有生成的 INSERT INTO 语句推给数据库执行

举例来说,如果调用 IService#saveBatch() 方法保存有2个元素的实体集合 List<node> 数据到数据库,其执行的 SQL 语句如下

存在 2 条:
INSERT INTO node (name, version) VALUES (&lsquo;nathan&rsquo;,1);
INSERT INTO node (name, version) VALUES (&lsquo;bob&rsquo;,1);

而如果是数据库批量插入,其执行的 SQL 语句应该如下

只有 1 条:
INSERT INTO node (name, version) VALUES (&lsquo;nathan&rsquo;,1), (&lsquo;bob&rsquo;,1);

    @Transactional(rollbackFor = Exception.class)    @Override    public boolean saveBatch(Collection<T> entityList, int batchSize) {        String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));    }        protected String sqlStatement(SqlMethod sqlMethod) {        return SqlHelper.table(entityClass).getSqlStatement(sqlMethod.getMethod());    }        protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {        Assert.isFalse(batchSize < 1, "batchSize must not be less than one");        return !CollectionUtils.isEmpty(list) && executeBatch(sqlSession -> {            int size = list.size();            int i = 1;            for (E element : list) {                consumer.accept(sqlSession, element);                if ((i % batchSize == 0) || i == size) {                    sqlSession.flushStatements();                }                i++;            }        });    }

2. MyBatis-plus 的批量插入方法

2.1 通用批量插入方法 InsertBatchSomeColumn

事实上 MyBatis-plus 提供了真正的批量插入方法 InsertBatchSomeColumn,只不过这个方法只在 MySQL 数据库下测试过,所以没有将其作为默认通用方法添加到 SqlMethod 中

从其源码实现不难看出,InsertBatchSomeColumn 其实就是提供了一个使用 foreach 标签的 SQL 脚本,不了解这个标签的读者参考自定义批量插入大致理解即可

@NoArgsConstructor@AllArgsConstructorpublic class InsertBatchSomeColumn extends AbstractMethod {        @Setter    @Accessors(chain = true)    private Predicate<TableFieldInfo> predicate;    @SuppressWarnings("Duplicates")    @Override    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {        KeyGenerator keyGenerator = new NoKeyGenerator();        SqlMethod sqlMethod = SqlMethod.INSERT_ONE;        List<TableFieldInfo> fieldList = tableInfo.getFieldList();        String insertSqlColumn = tableInfo.geTKEyInsertSqlColumn(false) +            this.filterTableFieldInfo(fieldList, predicate, TableFieldInfo::getInsertSqlColumn, EMPTY);        String columnScript = LEFT_BRACKET + insertSqlColumn.substring(0, insertSqlColumn.length() - 1) + RIGHT_BRACKET;        String insertSqlProperty = tableInfo.getKeyInsertSqlProperty(ENTITY_DOT, false) +            this.filterTableFieldInfo(fieldList, predicate, i -> i.getInsertSqlProperty(ENTITY_DOT), EMPTY);        insertSqlProperty = LEFT_BRACKET + insertSqlProperty.substring(0, insertSqlProperty.length() - 1) + RIGHT_BRACKET;        String valuesScript = SqlScriptUtils.convertForeach(insertSqlProperty, "list", null, ENTITY, COMMA);        String keyProperty = null;        String keyColumn = null;        // 表包含主键处理逻辑,如果不包含主键当普通字段处理        if (StringUtils.isNotBlank(tableInfo.getKeyProperty())) {            if (tableInfo.getIdType() == IdType.AUTO) {                                keyGenerator = new Jdbc3KeyGenerator();                keyProperty = tableInfo.getKeyProperty();                keyColumn = tableInfo.getKeyColumn();            } else {                if (null != tableInfo.getKeySequence()) {                    keyGenerator = TableInfoHelper.genKeyGenerator(getMethod(sqlMethod), tableInfo, builderAssistant);                    keyProperty = tableInfo.getKeyProperty();                    keyColumn = tableInfo.getKeyColumn();                }            }        }        String sql = String.fORMat(sqlMethod.getSql(), tableInfo.getTableName(), columnScript, valuesScript);        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);        return this.addInsertMappedStatement(mapperClass, modelClass, getMethod(sqlMethod), sqlSource, keyGenerator, keyProperty, keyColumn);    }    @Override    public String getMethod(SqlMethod sqlMethod) {        // 自定义 mapper 方法名        return "insertBatchSomeColumn";    }}

2.2 InsertBatchSomeColumn 的使用

由于InsertBatchSomeColumn 是框架已经定义好的通用方法,所以使用者只要引入即可,简单来说只需要进行以下几个步骤:

  • 新增 SQL 注入器

  • 新增配置类将 SQL 注入器添加到容器

  • 新增基类 Mapper,注意这个基类中的批量插入方法名称要和 InsertBatchSomeColumn#getMethod() 方法返回的字符串一致,也就是 insertBatchSomeColumn

具体做法读者请参考 MyBatis-plus 自定义通用方法及其实现原理,本文不再赘述

 经过以上配置,最终具体的业务类 Mapper 只要继承新增的基类 Mapper 就具备了批量插入的功能,笔者习惯将 Mapper 封装在一个 RepositoryService 中对外提供能力,则各个业务类只需要实现类似如下的 NodeRepositoryServiceImpl#insertBatch() 方法即可以对外提供批量插入的功能

    @Override    public int insertBatch(List<Node> entityList) {        if (CollectionUtils.isEmpty(entityList)) {            return 0;        }        return getBaseMapper().insertBatchSomeColumn(entityList);    }

3. 批量插入 Mysql 数据库的坑

3.1 mysql 对非 NULL 字段插入 NULL 值的处理

使用 MyBatis-plus 批量插入的方法插入 MySQL 记录时需要注意,调用批量插入的方法一定要保证确实是要插入多条数据,如果调用批量插入的方法只插入了单条数据,非常有可能遇到非 NULL 字段插入 NULL 值的错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'xxx_name' cannot be null

这是因为我们借助 Entity 插入数据时经常会忽略一些表中有默认值的非 NULL 字段对应的属性的赋值,而从批量插入的 SQL 语句的执行角度来看,这样做也就是往非 NULL 字段插入了 NULL 值。实际上 MySQL 对于非 NULL 字段插入 NULL 值是有兼容处理的,感兴趣的读者可前往 官方传送门,本文摘录如下:

简单来说,对于插入 NULL 值到非 NULL 字段的情况分为两种处理方式:

  • 如果是批量插入多条数据,则会将 NULL 值转化为默认值插到非 NULL 字段(也就是本文批量插入方法插入多条数据的情形)

  • 如果是单条数据插入,则抛出异常,失败结束(对应本文批量插入方法只插入了单条数据的情形)

Inserting NULL into a column that has been declared NOT NULL. For multiple-row INSERT statements or INSERT INTO ... SELECT statements, the column is set to the implicit default value for the columndata type. This is 0 for numeric types, the empty string ('') for string types, and the “zero” valuefor date and time types. INSERT INTO ... SELECT statements are handled the same way as multiple-rowinserts because the server does not examine the result set from the SELECT to see whether it returnsa single row. (For a single-row INSERT, no warning occurs when NULL is inserted into a NOT NULL column.Instead, the statement fails with an error.)

3.2 解决方法

解决方法很简单,只要在批量插入的时候判断一下 Entity 集合的大小即可,如果集合中只有一条数据,则调用插入单条数据的方法

  • MyBatis-plus 单条数据插入之所以不会有往非 NULL 字段插入 NULL 值的问题,是因为其单条插入数据的 SQL 脚本能根据 Entity 的属性赋值情况动态调整,对于 Entity 中值为 NULL 的属性,默认不会将其对应的字段添加到执行的 SQL 语句中

举例来说,如 Node 含有两个属性,分别是 name 和 version,则对于属性值不同的情况最终执行的 SQL 语句也不一样

version 为 NULL
INSERT INTO node (name) VALUES (&lsquo;nathan&rsquo;);
2. version 不为 NULL
INSERT INTO node (name, version) VALUES (&lsquo;nathan&rsquo;,1);

    @Override    public int insertBatch(List<Node> entityList) {        if (CollectionUtils.isEmpty(entityList)) {            return 0;        }        if (1 == entityList.size()) {            return getBaseMapper().insert(entityList.get(0));        }        return getBaseMapper().insertBatchSomeColumn(entityList);    }

到此,关于“MyBatis-plus批量插入的通用方法是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: MyBatis-plus批量插入的通用方法是什么

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

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

猜你喜欢
  • MyBatis-plus批量插入的通用方法是什么
    这篇文章主要介绍“MyBatis-plus批量插入的通用方法是什么”,在日常操作中,相信很多人在MyBatis-plus批量插入的通用方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis-p...
    99+
    2023-07-06
  • MyBatis-plus批量插入的通用方法使用
    目录1. MyBatis-plus 的批量保存方法2. MyBatis-plus 的批量插入方法2.1 通用批量插入方法 InsertBatchSomeColumn2.2 Inser...
    99+
    2023-05-15
    MyBatis-plus 批量插入的通用方法 MyBatis-plus 批量插入
  • Mybatis-plus---的批量插入
    批量插入 一、继承IService(伪批量) 二、insertBatchSomeColumn Mybatis-plus很强,为我们诞生了极简CURD操作,但对于数据批量操作,显然默认提供的insert方法是不够看的了,于是它和它来了!...
    99+
    2023-08-31
    mybatis java spring
  • Mybatis-Plus批量插入用法详解
    目录1. 准备测试环境2. saveBatch2.1 分析3. insert循环插入4. 自定义sql插入5. insertBatchSomeColumnmybatis-plus的I...
    99+
    2023-02-15
    Mybatis-Plus批量插入 Mybatis-Plus批量插入用法
  • MyBatis-Plus 批量插入数据的操作方法
    spring boot+mybatis plus环境,单条插入用的是BaseMapper自带的insert方法 public ApiResult addAnc(Anc anc) ...
    99+
    2024-04-02
  • Mybatis-Plus通过SQL注入器实现批量插入的实践
    目录前言一、mysql批量插入的支持二、Mybatis-Plus默认saveBatch方法解析1、测试工程建立2、默认批量插入saveBatch方法测试3、saveBatch方法实现...
    99+
    2022-11-13
    Mybatis-Plus SQL注入器批量插入 Mybatis-Plus 批量插入
  • 解决mybatis plus 批量插入方法不能用默认值的问题
    当使用InsertBatchSomeColumn 批量插入时,字段为null时会报错,而单条插入时会使用默认值,两者行为不统一,会对开发过程产生困扰。此方法改良了原版的批量插入方法,使得批量插入和单条插入结果一致。 由于mp的接口变化较快,...
    99+
    2023-09-09
    mybatis java mysql
  • Mybatis Plus 实现批量插入的示例代码
    目录一. 添加依赖二. 继承默认方法注入三. 在 MybatisPlusConfig 配置文件中注入 Bean四. 扩展自带 BaseMapper五. 业务层面实现Mybatis P...
    99+
    2024-04-02
  • MyBatis 批量插入数据的 3 种方法!
    数据库的最终效果如下: 1.循环单次插入 接下来我们将使用 Spring Boot 项目,批量插入 10W 条数据来分别测试各个方法的执行时间。​ 循环单次插入的(测试)核心代码如下: import com.example.de...
    99+
    2023-09-11
    mybatis java 数据库
  • MyBatis实现批量插入方法实例
    目录一、SQL实现示例二、Mybatis通过Mapper.xml文件实现三、在Mapper接口上使用注解四、限制一次批量插入数据的数量总结一、SQL实现示例 假设我们只插入一条数据的...
    99+
    2022-11-13
    mybatis批量插入 mybatis插入书籍
  • Mybatis-plus 批量插入太慢的问题解决(提升插入性能)
    MyBatis-Plus(简称MP)是一个MyBatis的增强工具,旨在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。 特点 无侵入:只做增强不做改变,引入它不会...
    99+
    2024-04-02
  • MyBatis批量插入的五种方式
    这里我列举了MyBatis和MyBatis-Plus常用的五种批量插入的方式,进行了详细的总结归纳。 一、准备工作 导入pom.xml依赖 mysql mysql-connector-java runtime or...
    99+
    2023-09-22
    mybatis java mysql
  • SQL Server批量插入数据的方法是什么
    在 SQL Server 中,有几种方法可以进行批量插入数据:1. 使用 INSERT INTO SELECT 语句:可以在...
    99+
    2023-09-16
    SQL Server
  • ORACLE大批量插入数据的方法是什么
    这篇文章主要介绍了ORACLE大批量插入数据的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ORACLE大批量插入数据的方法是什么文章都会有所收获,下面我们一起来看看吧。最近有几张表随着时间不断的增长...
    99+
    2023-07-05
  • Mybatis批量插入Oracle数据的方法实例
    目录基本环境需求方案改进带自增 id 的批量插入插入完成之后返回 sessionId注意事项总结Reference基本环境 语言:Java 8 数据库:Oracle ORM 框架:M...
    99+
    2024-04-02
  • mysql的批量插入是什么
    这篇文章主要讲解了“mysql的批量插入是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql的批量插入是什么”吧!说明批量插入是一种逐条优化数据插入的方式。批量插入数据的语法类似于...
    99+
    2023-06-20
  • Mybatis批量插入大量数据的方法有哪些
    本文小编为大家详细介绍“Mybatis批量插入大量数据的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Mybatis批量插入大量数据的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Mybat...
    99+
    2023-07-05
  • MyBatis批量插入数据的三种方法实例
    目录前言准备工作1.循环单次插入2.MP批量插入①控制器实现②业务逻辑层实现③数据持久层实现MP性能测试MP源码分析3.原生批量插入①业务逻辑层扩展②数据持久层扩展③添加UserMa...
    99+
    2024-04-02
  • Mybatis批量插入并返回主键id的方法
    目录场景错误分析原因排查问题场景 在做商城的时候,sku表进行了拆分,sku的基本信息以及sku的库存表。因为库存会经常的变动,会导致行锁。 这里就是新增的时候,因为在新增商品的时候...
    99+
    2024-04-02
  • Mybatis三种批量插入数据的方式
    目录1. 循环插入 2. foreach标签 3. 批处理 三种方式的对比 1. 循环插入 mapper.xml: <?xml version="1.0" enc...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作