MyBatis Plus 快速上手(简单易懂)

时间:2024-10-30 08:10:01

MyBatis Plus

国产的开源框架,基于 MyBatis

核心功能就是简化 MyBatis 的开发,提高效率。

MyBatis Plus 快速上手

Spring Boot + MyBatis Plus

1、创建 Maven 工程,选择相关配置
在这里插入图片描述

2、 引入 MyBatis Plus 的依赖

<dependency>
            <groupId></groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.1</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

3、创建实体类

package com.chen.mybatisplus.entity;

import lombok.Data;

@Data
public class User {

    private Integer id;
    private String name;
    private Integer age;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

4、创建 Mapper 接口

package com.chen.mybatisplus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.chen.mybatisplus.entity.User;

public interface UserMapper extends BaseMapper<User> {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5、

spring:
  datasource:
    driver-class-name: 
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 5846028
mybatis-plus:
  configuration:
    log-impl: 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

6、启动类需要添加 @MapperScan(“mapper所在的包”),否则无法加载 Mppaer bean。

package com.chen.mybatisplus;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("")
public class MybatisplusApplication {

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

7、测试类

package com.chen.mybatisplus.mapper;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void test() {
        userMapper.selectList(null).forEach(System.out::println);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

常用注解

@TableName

映射数据库的表名(如果不加默认实体类的小写为查询的数据表)

package com.chen.mybatisplus.entity;

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

@Data
@TableName(value = "user")
public class Account {
    private Integer id;
    private String name;
    private Integer age;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

@TableId

设置主键映射,value 映射主键字段名

type 设置主键类型,主键的生成策略,

AUTO(0),
NONE(1),
INPUT(2),
ASSIGN_ID(3),
ASSIGN_UUID(4),
/** @deprecated */
@Deprecated
ID_WORKER(3),
/** @deprecated */
@Deprecated
ID_WORKER_STR(3),
/** @deprecated */
@Deprecated
UUID(4);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
描述
AUTO 数据库自增
NONE MP set 主键,雪花算法实现
INPUT 需要开发者手动赋值
ASSIGN_ID MP 分配 ID,Long、Integer、String
ASSIGN_UUID 分配 UUID,Strinig

INPUT 如果开发者没有手动赋值,则数据库通过自增的方式给主键赋值,如果开发者手动赋值,则存入该值。

AUTO 默认就是数据库自增,开发者无需赋值。

ASSIGN_ID MP 自动赋值,雪花算法。

ASSIGN_UUID 主键的数据类型必须是 String,自动生成 UUID 进行赋值

@TableField

映射非主键字段,value 映射字段名

exist 表示是否为数据库字段 false,如果实体类中的成员变量在数据库中没有对应的字段,则可以使用 exist,VO、DTO

select 表示是否查询该字段

fill 表示是否自动填充,将对象存入数据库的时候,由 MyBatis Plus 自动给某些字段赋值,create_time、update_time

1、给表添加 create_time、update_time 字段

2、实体类中添加成员变量
package ;

import ;
import ;
import ;
import ;

import ;

@Data
public class User {

    @TableId()
    private Long id;

    @TableField(value = "name")
    private String title;

    @TableField(select = false)
    private Integer age;

    @TableField(exist = false)
    private String gender;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3、创建自动填充处理器

package com.chen.mybatisplus.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

4、测试类

package com.chen.mybatisplus.mapper;

import com.chen.mybatisplus.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void test() {
        userMapper.selectList(null).forEach(System.out::println);
    }

    @Test
    void save() {
        User user = new User();
        user.setTitle("李明");
        user.setAge(25);
        userMapper.insert(user);
    }

    @Test
    void update() {
        User user = userMapper.selectById(5);
        user.setTitle("小虎");
        userMapper.updateById(user);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

@Version

标记乐观锁,通过 version 字段来保证数据的安全性,当修改数据的时候,会以 version 作为条件,当条件成立的时候才会修改成功。

(乐观锁是处理并发的一种解决方案,防止数据被重复修改,当多个线程访问同个数据防止数据错乱的问题)

1、数据库表添加 version 字段,默认值为 1

2、实体类添加 version 成员变量,并且添加 @Version

@Data
public class User {

    @TableId()
    private Long id;

    @TableField(value = "name")
    private String title;

    @TableField(select = false)
    private Integer age;

    @TableField(exist = false)
    private String gender;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    @Version
    private Integer version;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

3、注册配置类

package com.chen.mybatisplus.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisPlusConfig {

    // 注册乐观锁插件(新版:3.4.0)
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;

        // 乐观锁插件(旧)
       /* @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor () {
            return new OptimisticLockerInterceptor();*/
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

@EnumValue

1、通用枚举类注解,将数据库字段映射成实体类的枚举类型成员变量

package com.chen.mybatisplus.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;

public enum StatusEnum {

    WORK(1,"上班"),
    REST(0,"休息");

    StatusEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @EnumValue
    private Integer code;
    private String msg;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

数据库表添加 version 字段,默认值为 1

@Data
public class User {

    @TableId()
    private Long id;

    @TableField(value = "name")
    private String title;

    @TableField(select = false)
    private Integer age;

    @TableField(exist = false)
    private String gender;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    @Version
    private Integer version;

    private StatusEnum status;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

type-enums-package: 
  
  • 1
  • 2

2、实现接口

package com.chen.mybatisplus.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;

public enum AgeEnum implements IEnum<Integer> {
    ONE(1,"一岁"),
    TWO(2,"两岁"),
    THREE(3,"三岁");

    private Integer code;
    private String msg;

    AgeEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public Integer getValue() {
        return this.code;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

@TableLogic

映射逻辑删除

1、数据表添加 deleted 字段

2、实体类添加注解

@Data
public class User {

    @TableId()
    private Long id;

    @TableField(value = "name")
    private String title;

    @TableField(select = false)
    private Integer age;

    @TableField(exist = false)
    private String gender;

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

    @Version
    private Integer version;

    private StatusEnum status;

    @TableLogic
    private Integer deleted;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3、 添加配置

global-config:
  db-config:
    logic-not-delete-value: 0
    logic-delete-value: 1
  • 1
  • 2
  • 3
  • 4

4、测试

@Test
    void delete() {
        userMapper.deleteById(1);
    }
  • 1
  • 2
  • 3
  • 4

查询

  • 一些简单查询
 @Test
    void select() {
      //不加任何条件全部查询
//(null);

QueryWrapper wrapper = new QueryWrapper();
//        Map<String,Object> map = new HashMap<>();
//        ("name","张三");
//        ("age",1);
//eq等值查询,allEq多条件查询
//        (map);
//gt大于查询
//        ("age",18);
//lt小于查询
//        ("age",25);
//ne不等查询
//        ("name","李四");
//ge大于等于查询
//        ("age",15);

//like模糊查询,把名字带有小的查出来
//        ("name","小");
//like '%小'  把名字带有小结尾的查出来
//        ("name","小");
//like '小%'  把名字带有小开头的查出来
//        ("name","小");

//inSQL 联合查询
//        ("id","select id from user where id < 10");
//        ("age","select age from user where age > 18");

//降序查询
//        ("age");

//升序查询
//        ("age");
//        ("id > 2");

mapper.selectList(wrapper).forEach(System.out::println);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 分页查询
 @Test
    void select() {
        //分页查询
        Page<User> page = new Page<>(1,2);
        Page<User> result = userMapper.selectPage(page,null);
        System.out.println(result.getSize());
        System.out.println(result.getTotal());
        result.getRecords().forEach(System.out::println);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

分页查询配置

@Configuration
public class MyBatisPlusConfig {
/*	旧版本配置
@Bean
public PaginationInterceptor paginationInterceptor(){
	return new PaginationInterceptor();
}*/

/**
 * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题
 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
	MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
	interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
	return interceptor;
}

@Bean
public ConfigurationCustomizer configurationCustomizer() {
	return configuration -> configuration.setUseDeprecatedExecutor(false);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

自定义 SQL(多表关联查询)

package com.chen.mybatisplus.entity;

import lombok.Data;

@Data
public class ProductVO {

    private Integer category;
    private String count;
    private String description;
    private Integer userId;
    private String userName;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
public interface UserMapper extends BaseMapper<User> {

    @Select("select p.*, userName from product p,user u where p.user_id =  and  = #{id}")
    List<ProductVO> productList(Integer id);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  @Test
    void product() {
        userMapper.productList(3).forEach(System.out::println);
    }
  • 1
  • 2
  • 3
  • 4

添加

 @Test
    void save() {
        User user = new User();
        user.setTitle("李明");
        user.setAge(25);
        userMapper.insert(user);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

删除

//(1);
//        ((2,3));
//        QueryWrapper wrapper = new QueryWrapper();
//        ("age",18);
//        (wrapper);

Map<String,Object> map = new HashMap<>();
map.put("id",10);
mapper.deleteByMap(map);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

修改


User user = mapper.selectById(1);
user.setTitle("小红");
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",22);
mapper.update(user,wrapper);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

MyBatisPlus 自动生成

根据数据表自动生成实体类、Mapper、Service、ServiceImpl、Controller

1、 导入 MyBatis Plus Generator

<dependency>
    <groupId></groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.3.</version>
</dependency>

<dependency>
    <groupId></groupId>
    <artifactId>velocity</artifactId>
    <version>1.7</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、启动类

package com.chen.mybatisplusgenerator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class Main {

    public static void main(String[] args) {
        //创建generator对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setPassword("5846028");
        dataSourceConfig.setDriverName("");
        autoGenerator.setDataSource(dataSourceConfig);
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("")+"/src/main/java");
        globalConfig.setOpen(false);
        globalConfig.setAuthor("chen");
        globalConfig.setServiceName("%sService");
        autoGenerator.setGlobalConfig(globalConfig);
        //包信息
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("");
        //指定生成在哪个包下,自己定义,null就是没有或者干脆不写这条语句
        packageConfig.setModuleName(null);
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("");
        packageConfig.setMapper("mapper");
        packageConfig.setEntity("entity");
        autoGenerator.setPackageInfo(packageConfig);
        //配置策略
        StrategyConfig strategyConfig = new StrategyConfig();
        //指定生成那些表,不写这条语句就默认把数据库中的所有表都生成出来
        //("user","user2","...");
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        autoGenerator.setStrategy(strategyConfig);

        autoGenerator.execute();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53