mybatisplus入门教程

mybatisplus入门教程

文章目录

  • mybatisplus入门教程
    • 什么是Mybatis Plus
    • 快速入门
      • 创建数据库 gk_mybatis_plus
      • 创建数据库表
      • 添加数据
      • 创建空的Spring Boot项目
      • 添加依赖
      • 配置数据库连接MySQL
      • 编写代码
        • 实体类 GkUserDomain
        • mapper
        • xml映射文件
        • 业务层,实现类
        • 控制层
        • 创建请求
        • 配置日志打印
    • 注解
      • @TableName
      • @TableId
      • @TableField
    • 自定义`id`生成器
    • 分页插件
    • 条件构造器
    • 批量操作
      • 批量录入开始
      • 方法一:Mybatis-plus 提供的 saveOrUpdateBatch 11s/1w数据
      • 方法二:分组数据再批量添加或修改
      • 方法三:mybatis动态SQL`foreach` 3s/w条数据
      • 批量录入结束
      • 批量查询开始
      • 方案一:内置方法selectBatchIds
      • 方法二:条件构造器QueryWrapper
      • 方案三:编写动态SQL实现
    • `sql`耗时
      • 添加依赖
      • yml配置
      • 添加属性文件spy.properties

  • 参考博客
    mybatisplus官网
    Mybatis Plus详细教程

什么是Mybatis Plus

mybatisplus入门教程_第1张图片

快速入门

创建数据库 gk_mybatis_plus

mybatisplus入门教程_第2张图片

创建数据库表

DROP TABLE IF EXISTS gk_user;
CREATE TABLE gk_user
(
    id    BIGINT(20)  NOT NULL COMMENT '主键ID',
    name  VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age   INT(11)     NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

添加数据


select *
from gk_user;

DELETE
FROM user;INSERT INTO gk_user (id, name, age, email)
VALUES (1, 'Jone', 18, '[email protected]'),
       (2, 'Jack', 20, '[email protected]'),
       (3, 'Tom', 28, '[email protected]'),
       (4, 'Sandy', 21, '[email protected]'),
       (5, 'Billie', 24, '[email protected]');

创建空的Spring Boot项目

1 创建项目目录
File->New->Project
在这里插入图片描述
2 选择脚手架,jdk版本
mybatisplus入门教程_第3张图片
Spring Initializr
Project SDK : java version “1.8.0_131”
choose Initializr Service URL.
Default: https://start.spring.io
3 Spring Boot基本信息
mybatisplus入门教程_第4张图片
注意:修改version:2.4.1
mybatisplus入门教程_第5张图片
mybatisplus入门教程_第6张图片
最终效果空项目
mybatisplus入门教程_第7张图片

添加依赖

父工程

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.4.1version>
        <relativePath/> 
    parent>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-configuration-processorartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.5.1version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>

注意:尽量不要同时导入mybatis和mybatis_plus,版本差异

配置数据库连接MySQL

# DataSource Config
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql:///mybatis_plus?userUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver

在spring boot启动类中添加@MapperScan注解,扫描Mapper文件夹

package com.geekmice.gkmybatisplusdemo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.geekmice.gkmybatisplusdemo.dao")
@SpringBootApplication
public class GkMybatisplusDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(GkMybatisplusDemoApplication.class, args);
    }

}

编写代码

实体类 GkUserDomain

package com.geekmice.gkmybatisplusdemo.domain;

/**
 * @BelongsProject: gk-mybatisplus-demo
 * @BelongsPackage: com.geekmice.gkmybatisplusdemo.domain
 * @Author: pingmingbo
 * @CreateTime: 2023-07-21  09:26
 * @Description: TODO
 * @Version: 1.0
 */

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;


/**
 * @TableName gk_user
 */
@Data
@TableName("gk_user")
public class GkUserDomain {
    /**
     * 主键ID
     */
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;

}

注意:@TableName("gk_user") ,这个注解是为了说明映射数据库表,默认gk_user_domain,类似于起别名作用。

mapper

package com.geekmice.gkmybatisplusdemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;

/**
 * @Entity com.geekmice.gkmybatisplusdemo.domain.GkUser
 */
public interface GkUserMapper extends BaseMapper<GkUserDomain> {


}

xml映射文件


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.geekmice.gkmybatisplusdemo.mapper.GkUserMapper">

    <resultMap id="BaseResultMap" type="com.geekmice.gkmybatisplusdemo.domain.GkUserDomain">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="age" column="age" jdbcType="INTEGER"/>
            <result property="email" column="email" jdbcType="VARCHAR"/>
    resultMap>

    <sql id="Base_Column_List">
        id,name,age,
        email
    sql>
mapper>

业务层,实现类

package com.geekmice.gkmybatisplusdemo.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;

import java.util.List;

/**
 *
 */
public interface GkUserService extends IService<GkUserDomain> {
    List<GkUserDomain> listFirst(Wrapper<GkUserDomain> queryWrapper);
}

package com.geekmice.gkmybatisplusdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;
import com.geekmice.gkmybatisplusdemo.mapper.GkUserMapper;
import com.geekmice.gkmybatisplusdemo.service.GkUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 */
@Service
public class GkUserServiceImpl extends ServiceImpl<GkUserMapper, GkUserDomain>
        implements GkUserService {
    @Autowired
    private GkUserMapper userMapper;

    @Override
    public List<GkUserDomain> listFirst(Wrapper<GkUserDomain> queryWrapper) {
        List<GkUserDomain> result = userMapper.selectList(null);
        return result;
    }
}

控制层

package com.geekmice.gkmybatisplusdemo.controller;

import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;
import com.geekmice.gkmybatisplusdemo.service.GkUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @BelongsProject: gk-mybatisplus-demo
 * @BelongsPackage: com.geekmice.gkmybatisplusdemo.controller
 * @Author: pingmingbo
 * @CreateTime: 2023-07-21  09:37
 * @Description: TODO
 * @Version: 1.0
 */
@RestController
@Slf4j
public class GkUserController {
    @Autowired
    private GkUserService gkUserService;

    @GetMapping("test")
    public List<GkUserDomain> test() {
        List<GkUserDomain> gkUserDomains = gkUserService.listFirst(null);
        log.info("abc");
        return gkUserDomains;
    }
}

创建请求

GET http://localhost:8080/test
Accept: application/json

###

mybatisplus入门教程_第8张图片

配置日志打印

yml

#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

mybatisplus入门教程_第9张图片

注解

@TableName

  • 描述:表名注解,映射实体类对应表
  • 实体类使用

/**
 * @TableName gk_user
 */
@Data
@TableName("gk_user")
public class GkUserDomain {
    /**
     * 主键ID
     */
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;

}

@TableId

说明:标识主键,实体类主键字段
没有添加注解@TableId,会生成一个序列号id,自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线)

  {
    "id": 1682215281188872194,
    "name": "zs",
    "age": 10,
    "email": "[email protected]"
  }

添加注解@TableId,没有什么变化,还是生成无序编号id

  {
    "id": 1682215919683575809,
    "name": "ls",
    "age": 11,
    "email": "[email protected]"
  }

type之IdType属性如下
mybatisplus入门教程_第10张图片

注意:数据库表主键字段需要设置为自增,整形
mybatisplus入门教程_第11张图片

mybatisplus入门教程_第12张图片自 3.3.0 开始,默认使用雪花算法+UUID(不含中划线)

@TableField

说明:非主键字段,起别名value=“”

package com.geekmice.gkmybatisplusdemo.domain;

/**
 * @BelongsProject: gk-mybatisplus-demo
 * @BelongsPackage: com.geekmice.gkmybatisplusdemo.domain
 * @Author: pingmingbo
 * @CreateTime: 2023-07-21  09:26
 * @Description: TODO
 * @Version: 1.0
 */

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;


/**
 * @TableName gk_user
 */
@Data
@TableName("gk_user")
public class GkUserDomain {
    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 姓名
     */
	@TableField(value="user_name")
    private String name;



}

自定义id生成器

分页插件

在这里插入代码片

条件构造器

 /**
     * @description 练习mybatis plus 条件构造器
     * @return
     */
    @GetMapping(value = "validQueryWrapper")
    public String validQueryWrapper(){
        QueryWrapper<GkUserDomain> userQueryWrapper = new QueryWrapper<>();
        // 1 查询用户表所有id列信息
        // QueryWrapper tempIdInfos = userQueryWrapper.select("id");
        // java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        // List domains = gkUserMapper.selectList(tempIdInfos);
        // List idList = gkUserMapper.selectObjs(userQueryWrapper);

        // 2 查询用户表某几列信息
        // 3 模糊查询
        // userQueryWrapper.likeLeft("name","mb"); // 左模糊
        // log.info("左模糊:[{}]",gkUserMapper.selectList(userQueryWrapper)); // SELECT id FROM gk_user WHERE (name LIKE '%mb')
        // userQueryWrapper.likeRight("name","pmb"); // 右模糊
        // log.info("右模糊:[{}]",gkUserMapper.selectList(userQueryWrapper)); // SELECT id FROM gk_user WHERE (name LIKE '%mb' AND name LIKE 'pmb%')

        // 4 分页查询 todo
        // 使用分页插件

        // 5 全部相等情况
        // HashMap allEqMap = new HashMap<>(16);
        // allEqMap.put("id","1682216842073970971");
        // allEqMap.put("name","pmb0");
        // allEqMap.put("age",10);
        // allEqMap.put("email","[email protected]");
        // userQueryWrapper.allEq(allEqMap);
        // log.info("全部相等:[{}]",gkUserMapper.selectList(userQueryWrapper));
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user
        // WHERE (name = 'pmb0' AND id = '1682216842073970971' AND age = 10 AND email = '[email protected]')

        // 6 eq 某个字段相等
        String paramFirst = "abc";
        // // userQueryWrapper.eq("name","pmb1");
        // userQueryWrapper.eq(StringUtils.isNotBlank(paramFirst),"name","pmb2");
        // // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name = 'pmb2')
        // gkUserMapper.selectList(userQueryWrapper);

        //
        // 7 ne 某个字段不相等/外加条件某个字段不相等
        // userQueryWrapper.ne("name","pmb3");
        // userQueryWrapper.ne(StringUtils.contains(paramFirst,"a"),"age","18");
        // gkUserMapper.selectList(userQueryWrapper);
        //SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name <> 'pmb3')
        //SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age <> '18')


        // // 8 排序 asc desc
        // userQueryWrapper.orderByAsc("age");
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user ORDER BY age ASC 升序
        // userQueryWrapper.orderByDesc("age");
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user ORDER BY age DESC 降序
        // gkUserMapper.selectList(userQueryWrapper);

        // // 9 是否为空
        // userQueryWrapper.isNull("name");
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name IS NULL);
        // userQueryWrapper.isNotNull("name");
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name IS NOT NULL)
        // gkUserMapper.selectList(userQueryWrapper);
        //
        // // 10 大于
        // userQueryWrapper.gt("age",19);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age > 19)
        // gkUserMapper.selectList(userQueryWrapper);
        //
        // // 11 大于等于
        // userQueryWrapper.ge("age",20);
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age >= 20)

        //
        // // 12 小于
        // userQueryWrapper.lt("age",11);
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age < 11)

        //
        // // 13 小于等于
        // userQueryWrapper.le("age",22);
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age <= 22)
        //
        // // 14 在a与b之间 between
        // userQueryWrapper.between("age",18,20);
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age BETWEEN 18 AND 20)
        //
        // // 15 不在a,b之间 notBetween
        // userQueryWrapper.notBetween("age",18,20);
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (age NOT BETWEEN 18 AND 20)

        //
        // // 16 在哪几个之内 in
        // userQueryWrapper.in("name","pmb1","pmb2");
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name IN ('pmb1','pmb2'))

        // // 17 不在哪几个之内 notIn
        // userQueryWrapper.notIn("name","pmb1","pmb2","pm3");
        // gkUserMapper.selectList(userQueryWrapper);
        //SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name NOT IN ('pmb1','pmb2','pm3'))
        // // 18 inSql
        // userQueryWrapper.inSql("name","pmb");
        // userQueryWrapper.inSql("name","select name from gk_user where name like '%4'");
        // gkUserMapper.selectList(userQueryWrapper);
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (name IN (select name from gk_user where name like '%4'))

        //
        // // 19 notInSql
        // userQueryWrapper.notInSql("name","pmb1,pmb2,pmb3");
        //
        // // 20 分组 groupBy
        // userQueryWrapper.groupBy("age");
        //
        // // 21 or 或者
        // // 主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
        userQueryWrapper.inSql("name","select name from gk_user where name like '%4'")
                .or()
                .inSql("name","select name from gk_user where name like '%6'");
        gkUserMapper.selectList(userQueryWrapper);
        //
        // SELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE
        // (name IN (select name from gk_user where name like '%4') OR
        // name IN (select name from gk_user where name like '%6'))

        // return idList.toString();
        return "success";
    }

批量操作

批量录入开始

方法一:Mybatis-plus 提供的 saveOrUpdateBatch 11s/1w数据

controller

package com.geekmice.gkmybatisplusdemo.controller;

import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;
import com.geekmice.gkmybatisplusdemo.service.GkUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @BelongsProject: gk-mybatisplus-demo
 * @BelongsPackage: com.geekmice.gkmybatisplusdemo.controller
 * @Author: pingmingbo
 * @CreateTime: 2023-07-21  09:37
 * @Description: TODO
 * @Version: 1.0
 */
@RestController
@Slf4j
public class GkUserController {
    @Autowired
    private GkUserService gkUserService;
    public static List<GkUserDomain> tempData = new ArrayList(16);

    static {
        for (int i = 0; i < 10000; i++) {
            GkUserDomain user = GkUserDomain.builder().age(i + 10)
                    .email("abc" + i + "@163.com").name("pmb" + i)
                    .field1("f" + i)
                    .field2("f" + i)
                    .field3("f" + i)
                    .field4("f" + i)
                    .field5("f" + i)
                    .field6("f" + i)
                    .build();
            tempData.add(user);
        }
    }

    /**
     * @return
     * @description 第一个demo
     */
    @GetMapping("test")
    public List<GkUserDomain> test() {
        List<GkUserDomain> gkUserDomains = gkUserService.listFirst(null);
        log.info("abc");
        return gkUserDomains;
    }

    /**
     * @param user
     * @return
     * @description 添加用户
     */
    @PostMapping(value = "addUser")
    public String addUser(@RequestBody GkUserDomain user) {
        gkUserService.save(user);
        return "success";
    }

    /**
     * @param list
     * @return
     * @description 批量添加
     */
    @PostMapping(value = "saveBatch")
    public String saveBatch() {
        long start = System.currentTimeMillis();
        gkUserService.saveOrUpdateBatch(tempData);
        long end = System.currentTimeMillis();
        log.info("批量录入1w耗时:【{}】s", (end - start) / 1000);
        return "success";
    }
}

业务层service,serviceimpl

package com.geekmice.gkmybatisplusdemo.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;

import java.util.List;

/**
 *
 */
public interface GkUserService extends IService<GkUserDomain> {
    List<GkUserDomain> listFirst(Wrapper<GkUserDomain> queryWrapper);
}

package com.geekmice.gkmybatisplusdemo.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;
import com.geekmice.gkmybatisplusdemo.mapper.GkUserMapper;
import com.geekmice.gkmybatisplusdemo.service.GkUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 *
 */
@Service
public class GkUserServiceImpl extends ServiceImpl<GkUserMapper, GkUserDomain>
        implements GkUserService {
    @Autowired
    private GkUserMapper userMapper;

    @Override
    public List<GkUserDomain> listFirst(Wrapper<GkUserDomain> queryWrapper) {
        List<GkUserDomain> result = userMapper.selectList(null);
        return result;
    }
}


数据层mapper

package com.geekmice.gkmybatisplusdemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.geekmice.gkmybatisplusdemo.domain.GkUserDomain;

/**
 * @Entity com.geekmice.gkmybatisplusdemo.domain.GkUser
 */
public interface GkUserMapper extends BaseMapper<GkUserDomain> {


}

mapper映射文件


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.geekmice.gkmybatisplusdemo.mapper.GkUserMapper">

    <resultMap id="BaseResultMap" type="generator.domain.GkUser">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="age" column="age" jdbcType="INTEGER"/>
            <result property="email" column="email" jdbcType="VARCHAR"/>
            <result property="field1" column="field1" jdbcType="VARCHAR"/>
            <result property="field2" column="field2" jdbcType="VARCHAR"/>
            <result property="field3" column="field3" jdbcType="VARCHAR"/>
            <result property="field4" column="field4" jdbcType="VARCHAR"/>
            <result property="field5" column="field5" jdbcType="VARCHAR"/>
            <result property="field6" column="field6" jdbcType="VARCHAR"/>
    resultMap>

    <sql id="Base_Column_List">
        id,name,age,
        email,field1,field2,
        field3,field4,field5,
        field6
    sql>
mapper>

实体类domain

package com.geekmice.gkmybatisplusdemo.domain;

/**
 * @BelongsProject: gk-mybatisplus-demo
 * @BelongsPackage: com.geekmice.gkmybatisplusdemo.domain
 * @Author: pingmingbo
 * @CreateTime: 2023-07-21  09:26
 * @Description: TODO
 * @Version: 1.0
 */

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;


/**
 * @TableName gk_user
 */
@Data
@TableName("gk_user")
@Builder
public class GkUserDomain {
    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 邮箱
     */
    private String email;
    /**
     * 备注1
     */
    private String field1;
    /**
     * 备注2
     */
    private String field2;
    /**
     * 备注3
     */
    private String field3;
    /**
     * 备注4
     */
    private String field4;
    /**
     * 备注5
     */
    private String field5;
    /**
     * 备注6
     */
    private String field6;

}

效果

POST http://localhost:8080/saveBatch

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 7
Date: Fri, 21 Jul 2023 03:26:03 GMT
Keep-Alive: timeout=60
Connection: keep-alive

success

Response code: 200; Time: 11603ms; Content length: 7 bytes

方法二:分组数据再批量添加或修改

核心思想
先获取数据库表中所有id,从带落库的数据中找到数据库表已经有的id,这样的更新操作;
否则落库。

核心代码

    /**
     * @param list
     * @return
     * @description 批量添加2
     */
    @PostMapping(value = "saveBatchOptionTwo")
    public String saveBatchOptionTwo() {
        List<GkUserDomain> result = gkUserService.list();
        List<Long> idList = result.stream().map(GkUserDomain::getId).collect(Collectors.toList());
        // // 分组
        Map<Boolean, List<GkUserDomain>> flagMap = tempData.stream().collect(Collectors.groupingBy(b -> {
            return idList.contains(b.getId());
        }));
        // true:更新 false:修改
        gkUserService.updateBatchById(flagMap.get(true));
        gkUserService.saveBatch(flagMap.get(false));

        return "success";
    }
POST http://localhost:8080/saveBatchOptionTwo

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 7
Date: Fri, 21 Jul 2023 04:20:12 GMT
Keep-Alive: timeout=60
Connection: keep-alive

success

Response code: 200; Time: 1268ms; Content length: 7 bytes

方法三:mybatis动态SQLforeach 3s/w条数据

注意:然MyBatis的动态标签的批量操作在数据量特别大的时候,拼接出来的SQL语句过大;
MySQL的服务端对于接收的数据包有大小限制,max_allowed_packet 默认是 4M,需要修改默认配
置或者手动地控制条数,才可以解决这个问题。
3s/1w条数据
优化思路:

static int batchSize = 10000;
 
public void createBatch(List<TestPO> entityList) {
    if (!entityList.isEmpty()) {
        int size = entityList.size();
        int idxLimit = Math.min(batchSize, size);
        int i = 1;
        List<TestPO> oneBatchList = new ArrayList<>();
        for (Iterator<TestPO> var7 = entityList.iterator(); var7.hasNext(); ++i) {
            TestPOelement = var7.next();
            oneBatchList.add(element);
            if (i == idxLimit) {
                baseMapper.insertBatchSomeColumn(oneBatchList);
                oneBatchList.clear();
                idxLimit = Math.min(idxLimit + batchSize, size);
            }
        }
    }
}
<insert id="batchSaveMybatis" parameterType="java.util.List">
        <foreach collection="list" open="begin" close="end;" separator="," item="data">
            insert into gk_user values (
            #{data.name,javaType="INTEGER"},
            #{data.age,javaType="VARCHAR"},
            #{data.email,javaType="VARCHAR"},
            #{data.field1,javaType="VARCHAR"},
            #{data.field2,javaType="VARCHAR"},
            #{data.field3,javaType="VARCHAR"},
            #{data.field4,javaType="VARCHAR"},
            #{data.field5,javaType="VARCHAR"},
            #{data.field6,javaType="VARCHAR"}
            )
        </foreach>
    </insert>

mybatisplus入门教程_第13张图片

批量录入结束

批量查询开始

方案一:内置方法selectBatchIds

selectBatchIds根据主键查询
List<Employee> emps=employeeMapper.selectBatchIds(Arrays.asList(1,2,13,14) );

方法二:条件构造器QueryWrapper

List<Long> idList = new ArrayList<>(); // 批量查询的 ID 列表
// 添加要查询的 ID 到 idList 中

QueryWrapper<Entity> queryWrapper = new QueryWrapper<>();
queryWrapper.in("id", idList); // 设置查询条件,in("id", idList) 表示查询 id 字段在 idList 中的记录

List<Entity> entityList = entityMapper.selectList(queryWrapper); // 执行批量查询

方案三:编写动态SQL实现

<select id="studentList" resultType="com.ywt.springboot.model.Student">
        select *
        from student
        where id in
        <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>

注:foreach中的 collection标签中为array,item是遍历ids中的每个元素,默认为item可以自定义。

sql耗时

在这里插入图片描述

 Consume Time5 ms 2023-07-22 16:20:27
 Execute SQLSELECT id,name,age,email,field1,field2,field3,field4,field5,field6 FROM gk_user WHERE (id = '1682216842073980917')

添加依赖

        
        
        <dependency>
            <groupId>p6spygroupId>
            <artifactId>p6spyartifactId>
            <version>3.8.6version>
        dependency>

yml配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:p6spy:mysql://localhost:3306/gk_mybatis-plus?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true&serverTimezone=UTC&useSSL=false&allowMultiQueries=true
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver

mybatisplus入门教程_第14张图片

添加属性文件spy.properties

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

你可能感兴趣的:(Mybatis,Plus,java,开发语言)