深入解析Mybatis-Plus框架:简化Java持久层开发(十二)

news2024/11/14 20:22:22

🍀 前言

博客地址:

  • CSDN:https://blog.csdn.net/powerbiubiu

👋 简介

本章节介绍如何通过Mybatis-Plus进行实现批量新增。

📖 正文

1 为何要批量插入?

前面章节已经介绍,Mapper接口只有一个insert单挑插入的方法,而Service接口中批量插入saveBatch的方法,也只能做到伪批量插入,实际还是利用了循环一条一条插入,这样会导致效率低,耗时长。
实际执行的SQL为

INSERT INTO tb_role ( role_name, role_code ) VALUES ( '超级管理员', 'ADMIN' )
INSERT INTO tb_role ( role_name, role_code ) VALUES ( '测试角色1号', 'TEST01' )
INSERT INTO tb_role ( role_name, role_code ) VALUES ( '测试角色2号', 'TEST02' )
INSERT INTO tb_role ( role_name, role_code ) VALUES ( '测试角色3号', 'TEST03' )

那么,我们该如何保证SQL的执行像下面这样执行呢,接下来我们开始进行操作

INSERT INTO 
	tb_role ( role_name, role_code ) 
VALUES 
	( '超级管理员', 'ADMIN' ),
	( '测试角色1号', 'TEST01' ),
	( '测试角色2号', 'TEST02' ),
	( '测试角色3号', 'TEST03' );

2 实现批量插入

这里我们将通过Mybatis-Plus框架的SQL注入器实现一个真的批量插入功能。

2.1 创建SQL注入器

在项目config目录下新增一个InsertBatchInjector类,然后继承DefaultSqlInjector类后,重新实现getMethodList方法。

package com.power.mpdemo.config;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.extension.injector.methods.InsertBatchSomeColumn;

import java.util.List;

/**
 * @author power
 * @time 2023/12/23 07:50:28
 * @Description
 */
public class InsertBatchInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        // super.getMethodList() 保留 Mybatis-Plus 自带的方法
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        // 添加自定义方法:批量插入,方法名为 insertBatchSomeColumn
        methodList.add(new InsertBatchSomeColumn());
        return methodList;
    }
}

在配置类中,添加了Mybatis-Plus内部提供的默认批量插入的InsertBatchSomeColumn类,根据作者在源码中的描述,只在Mysql数据库中测试过,所以没有将该方法提供外部使用,所以当前我们这里批量插入只针对Mysql数据库。
image.png

2.2 配置SQL注入器

在前面章节,我们在config包下创建的MybatisPlusConfig类中,添加以下代码

/**
 * 自定义批量插入 SQL 注入器
 *
 * @return
 */
@Bean
public InsertBatchInjector insertBatchSqlInjector() {
    return new InsertBatchInjector();
}
2.3 配置BaseMapper

config包下,新增一个NewBaseMapper的接口,继承Mybatis-Plus的BaseMapper接口。

package com.power.mpdemo.config;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author power
 * @time 2023/12/23 08:04:55
 * @Description
 */
public interface NewBaseMapper<T> extends BaseMapper<T> {

    // 批量插入
    int insertBatchSomeColumn(@Param("list") List<T> batchList);

}

修改我们的RoleMapper继承的接口为刚才创建的新接口

package com.power.mpdemo.mapper;

import com.power.mpdemo.config.NewBaseMapper;
import com.power.mpdemo.entity.Role;

/**
 * <p>
 * 角色表 Mapper 接口
 * </p>
 *
 * @author power
 * @since 2023-12-21
 */
public interface RoleMapper extends NewBaseMapper<Role> {

}
2.4 测试执行
@Test
public void insertBatch() {
    List<Role> list = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        list.add(Role.builder()
                .roleName("批量添加" + i)
                .roleCode("batch" + i)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .isDeleted(0)
                .build()
        );
    }
    int i = roleMapper.insertBatchSomeColumn(list);
    System.out.println("添加结果:" + i);
}

// 添加结果:5

实际执行的SQL

INSERT INTO 
	tb_role (role_name,role_code,description,create_time,update_time,is_deleted) 
VALUES 
	('批量添加0','batch0',NULL,'2023-12-23T08:14:29.860','2023-12-23T08:14:29.860',0) , 
  ('批量添加1','batch1',NULL,'2023-12-23T08:14:29.860','2023-12-23T08:14:29.860',0) , 
  ('批量添加2','batch2',NULL,'2023-12-23T08:14:29.860','2023-12-23T08:14:29.860',0) , 
  ('批量添加3','batch3',NULL,'2023-12-23T08:14:29.860','2023-12-23T08:14:29.860',0) , 
  ('批量添加4','batch4',NULL,'2023-12-23T08:14:29.860','2023-12-23T08:14:29.860',0)

3 性能对比

3.1 for循环插入
@Test
public void insertBatch() {
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        Role role = Role.builder()
        .roleName("for循环" + i)
        .roleCode("insert" + i)
        .createTime(LocalDateTime.now())
        .updateTime(LocalDateTime.now())
        .isDeleted(0)
        .build();
        roleMapper.insert(role);
    }
    System.out.printf("总耗时:%s ms%n", System.currentTimeMillis() - start);
}

// 总耗时:11460 ms
3.2 Service接口批量插入
@Test
public void insertBatch() {
    long start = System.currentTimeMillis();
    List<Role> list = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        list.add(Role.builder()
                .roleName("Service伪批量插入" + i)
                .roleCode("saveBatch" + i)
                .build()
        );
    }
    roleService.saveBatch(list);
    System.out.printf("总耗时:%s ms%n", System.currentTimeMillis() - start);
}

// 总耗时:1743 ms
3.3 真实批量插入
@Test
public void insertBatch() {
    long start = System.currentTimeMillis();
    List<Role> list = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        list.add(Role.builder()
                .roleName("批量添加" + i)
                .roleCode("batch" + i)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .isDeleted(0)
                .build()
        );
    }
    roleMapper.insertBatchSomeColumn(list);
    System.out.printf("总耗时:%s ms%n", System.currentTimeMillis() - start);
}

// 总耗时:252 ms

Tips:
根据执行结果发现,在插入数量同为10000条数据的情况下,for循环耗时最多,我们自己实现的真实批量插入耗时最少。尽管实际应用中我们不会使用for的方式批量插入,但是同样通过Mybatis-Plus框架实现的批量插入,Service接口的saveBatch方法的批量插入的耗时是自定义实现批量插入耗时的的6-7倍,当数据量十万百万级别的,就能体现出真实批量插入的性能的重要性了

✏ 总结

💖 欢迎关注我的公众号

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1534570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

那些场景需要额外注意线程安全问题

主要学习那些场景需要额外注意线程安全问题&#xff0c;在这里总结了四中场景。 访问共享变量或资源 第一种场景是访问共享变量或共享资源的时候&#xff0c;典型的场景有访问共享对象的属性&#xff0c;访问static静态变量&#xff0c;访问共享的缓存&#xff0c;等等。因为…

React 系列 之 React Hooks(一) JSX本质、理解Hooks

借鉴自极客时间《React Hooks 核心原理与实战》 JSX语法的本质 可以认为JSX是一种语法糖&#xff0c;允许将html和js代码进行结合。 JSX文件会通过babel编译成js文件 下面有一段JSX代码&#xff0c;实现了一个Counter组件 import React from "react";export defau…

【机器学习】深入解析线性回归模型

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

原创!分解+集成思想新模型!VMD-CNN-BiGRU-Attention一键实现时间序列预测!以风速数据集为例

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 目录 数据介绍 模型流程 创新点 结果展示 部…

【系统架构设计师】计算机系统基础知识 03

系统架构设计师 - 系列文章目录 01 系统工程与信息系统基础 02 软件架构设计 03 计算机系统基础知识 文章目录 系统架构设计师 - 系列文章目录 文章目录 前言 一、计算机系统概述 1.计算机组成 ​编辑2.存储系统 二、操作系统 ★★★★ 1.进程管理 2.存储管理 1.页式存储 …

Java:设计模式

文章目录 参考简介工厂模式简单工厂模式工厂方法模式抽象工厂模式总结 单例模式预加载懒加载线程安全问题 策略模式 参考 知乎 简介 总体来说设计模式分为三类共23种。 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模…

Java 22正式发布,一文了解全部新特性

就在昨晚&#xff0c;Java 22正式发布&#xff01;该版本提供了 12 项功能增强&#xff0c;其中包括 7 项预览功能和 1 项孵化器功能。它们涵盖了对 Java 语言、API、性能以及 JDK 中包含的工具的改进。 下面就来一起学习一下该版本都更新了哪些新特性&#xff01; Unnamed V…

世媒讯软文营销策略如何做才能达到引流的目的

软文营销是一种通过撰写软文来宣传企业、产品或服务的网络营销方式。通过撰写具有故事性、吸引人的文章来间接推广产品、服务或品牌的营销策略。要实现软文营销的目的&#xff0c;即引流&#xff08;吸引流量&#xff09;&#xff0c;以下是一些有效的策略&#xff1a; 新闻策略…

学点儿Java_Day7_继承、重载、重写、多态、抽象类

1 继承 1.1 概念与理解 继承&#xff1a; 你继承谁你就是谁&#xff0c;继承是一种严格的父子关系&#xff08;抽取到父类里面的属性和方法一定是所有子类所共有&#xff09;      &#xff08;Student继承Person&#xff0c;那么Student就是人&#xff09; 面向对象特征…

数据结构:初识树和二叉树

目前主流的方式是左孩子右兄弟表示法 我们的文件系统就是一个树 以上就是树的概念&#xff0c;我们今天还要来学习一种从树演变的重要的结构&#xff1a;二叉树 顾名思义二叉树就是一个结点最多有两个子树。 其中我们还要了解满二叉树和完全二叉树的概念 注意我们的完全二叉…

四、C语言中的数组:如何输入与输出二维数组(数组,完)

本章的学习内容如下 四、C语言中的数组&#xff1a;数组的创建与初始化四、C语言中的数组&#xff1a;数组的输入与元素个数C语言—第6次作业—十道代码题掌握一维数组四、C语言中的数组&#xff1a;二维数组 1.二维数组的输入与输出 当我们输入一维数组时需要一个循环来遍历…

10.注册页面

注册页面 在pages中新建页面register 复制粘贴之前的登录页面 设置上传头像图片 微信官方文档 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/userProfile.html <button class"avatar-wrapper" open-type"chooseAvatar&quo…

微调alpaca-lora遇到的一些问题

1、环境简介 环境&#xff1a; 系统&#xff1a;Ubuntu torch&#xff1a;2.2.1 python&#xff1a;3.10 gpu&#xff1a;V100 16g peft&#xff1a;0.9.0 使用PEFT中的lora方式微调llama-2-7b-hf&#xff0c;项目地址&#xff1a;alpaca-lora 2、混合精度训练Tensor相互计算会…

海外重要行业媒体:知名服务商IntoTheBlock现已集成波场TRON网络分析数据

近日,领先链上分析服务提供商 IntoTheBlock 宣布已将波场 TRON 网络集成至其市场情报套件。该合作引发多家海外加密媒体关注,Crypto Slate、Crypto Briefing等均对此进行了报道,称此次合作意义深远,能帮助数百万用户更深入地了解波场TRON生态系统。 报道表示,波场TRON网络规模大…

中文编程入门(Lua5.4.6中文版)第十一章 Lua 模块与包 参考星争际霸游戏

在遥远的星争际霸世界中&#xff0c;代码模块就如同星际基地中的高科技仓库&#xff0c;储存着各类经过封装优化的战术指令和战略资源。自Lua 5.1版本起&#xff0c;星际编程者们引入了标准化的模块管理系统&#xff0c;使得不同战舰之间能够共享和调用核心战斗算法&#xff0c…

Linux-网络层IP协议、链路层以太网协议解析

目录 网络层&#xff1a;IP协议地址管理路由选择 链路层 网络层&#xff1a; 网络层&#xff1a;负责地址管理与路由选择 — IP协议&#xff0c;地址管理&#xff0c;路由选择 IP协议 数据格式&#xff1a; 4位协议版本&#xff1a;4-ipv4协议版本 4位首部长度&#xff1a;以…

Redis实战:缓存穿透及其解决思路 实战演示

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

Python爬虫框架大比拼!从小爬虫到大数据采集|电商大数据采集API接口

在互联网时代&#xff0c;数据是无处不在的黄金。无论你是寻找小规模的数据采集任务还是大规模的网络爬虫项目&#xff0c;Python提供了丰富的爬虫框架供你选择。对于小型爬虫需求&#xff0c;你可能会喜欢使用requests库和Beautiful Soup(bs4库)这样的基本工具&#xff0c;它们…

想当初级爬虫工程师,需要把爬虫学到什么程度?

这篇文章会说说我自己的心得体验&#xff0c;关于爬虫、关于工作&#xff0c;仅供参考。 学到哪种程度 暂且把目标定位初级爬虫工程师&#xff0c;简单列一下吧&#xff1a; &#xff08;必要部分&#xff09; 语言选择&#xff1a;一般是了解Python、Java、Golang之一 熟悉…