MyBatis Plus 的基本用法

MyBatis Plus

国产的开源框架,基于 MyBatis

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

MyBatis Plus 快速上手

Spring Boot + MyBatis Plus

1、创建 Maven 工程,选择相关配置
MyBatis Plus 的基本用法

2、pom.xml 引入 MyBatis Plus 的依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.1</version>
        </dependency>

3、创建实体类

package com.chen.mybatisplus.entity;

import lombok.Data;

@Data
public class User {

    private Integer id;
    private String name;
    private Integer age;
}

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> {
}

5、application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 5846028
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

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("com.chen.mybatisplus.mapper")
public class MybatisplusApplication {

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

}

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);
    }

}

常用注解

@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;
}

@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);
描述
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 com.chen.mybatisplus.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.util.Date;

@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;
}

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);
    }
}

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);
    }
}

@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;
}

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();*/
    }
}

@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;
}

数据库表添加 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;
}

application.yml

type-enums-package: 
  com.southwind.mybatisplus.enums

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;
    }
}

@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;
}

3、application.yml 添加配置

global-config:
  db-config:
    logic-not-delete-value: 0
    logic-delete-value: 1

4、测试

@Test
    void delete() {
        userMapper.deleteById(1);
    }

查询

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

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

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

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

//降序查询
//        wrapper.orderByDesc("age");

//升序查询
//        wrapper.orderByAsc("age");
//        wrapper.having("id > 2");

mapper.selectList(wrapper).forEach(System.out::println);
    }
  • 分页查询
 @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);
    }

分页查询配置

@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);
}
}

自定义 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;
}
public interface UserMapper extends BaseMapper<User> {

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

添加

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

删除

//mapper.deleteById(1);
//        mapper.deleteBatchIds(Arrays.asList(2,3));
//        QueryWrapper wrapper = new QueryWrapper();
//        wrapper.eq("age",18);
//        mapper.delete(wrapper);

Map<String,Object> map = new HashMap<>();
map.put("id",10);
mapper.deleteByMap(map);

修改


User user = mapper.selectById(1);
user.setTitle("小红");
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("age",22);
mapper.update(user,wrapper);
上一篇:MyBatis-Plus 字段自动注入


下一篇:SpringBoot中的自动代码生成 - 基于Mybatis-Plus