MyBatis-Plus 学习笔记

MyBatis Plus

本文档基于 MyBatis-Plus 官方文档编写,详情请参见 MyBatis-Plus 官网 ,通过 Spring 和 Spring Boot 两种方式分别进行了实现。

MyBatis Plus 概述

MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上增强了功能而不做改变,为了简化开发、开发效率而生。

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

  • mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver
  • 达梦数据库 、 虚谷数据库 、 人大金仓数据库

入门程序

基本步骤

1、创建项目

2、导入依赖

3、编写相应配置文件

4、使用

数据库语句

数据库语句

CREATE DATABASE mybatisplus;

USE mybatisplus;

DROP TABLE IF EXISTS user;

CREATE TABLE 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)
);

数据库 Data 脚本

DELETE FROM user;

INSERT INTO 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 步骤

使用 Spring 步骤

1、创建 Maven 项目

2、 引入相应的依赖


    UTF-8
    1.8
    1.8
    5.0.2.RELEASE
    1.6.6
    1.2.12
    8.0.16
    3.4.5



    
    
    
        org.springframework
        spring-context
        ${spring.version}
    
    
        org.springframework
        spring-web
        ${spring.version}
    
    
        org.springframework
        spring-webmvc
        ${spring.version}
    
    
        org.springframework
        spring-test
        ${spring.version}
    
    
        org.springframework
        spring-tx
        ${spring.version}
    
    
        org.springframework
        spring-jdbc
        ${spring.version}
    
    
        junit
        junit
        4.12
        compile
    
    
        mysql
        mysql-connector-java
        ${mysql.version}
    
    
        javax.servlet
        servlet-api
        2.5
        provided
    
    
        javax.servlet.jsp
        jsp-api
        2.0
        provided
    
    
        jstl
        jstl
        1.2
    
    
    
        log4j
        log4j
        ${log4j.version}
    
    
        org.slf4j
        slf4j-api
        ${slf4j.version}
    
    
        org.slf4j
        slf4j-log4j12
        ${slf4j.version}
    
    
    
        com.baomidou
        mybatis-plus
        3.3.1
    
    
        com.baomidou
        mybatis-plus-generator
        3.3.1
    
    
        com.alibaba
        druid
        1.1.10
    
    
        org.projectlombok
        lombok
        1.18.12
        compile
    


3、编写配置文件 applicationContext.xml



    
    
    
    
    
    
        
        
        
        
    
    
    
        
    
    
    
        
    
    
    
        
    
    


4、编写 pojo 类和 mapper 接口

pojo 类

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

mapper 接口

@Repository
public interface UserMapper extends BaseMapper {}

5、 测试运行

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class UserTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void test01(){
        List users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
}

测试结果

MyBatis-Plus 学习笔记_第1张图片
1587958492400.png

使用 Spring Boot 步骤

使用 Spring Boot 步骤

1、创建 Spring Boot 项目

2、添加依赖


        org.springframework.boot
        spring-boot-starter-parent
        2.2.6.RELEASE
         
    

    
        mysql
        mysql-connector-java
        8.0.16
    
    
        org.projectlombok
        lombok
        1.18.12
    
    
        com.baomidou
        mybatis-plus-boot-starter
        3.3.1
    

    
        org.springframework.boot
        spring-boot-starter-web
    

    
        org.springframework.boot
        spring-boot-starter-test
        test
        
            
                org.junit.vintage
                junit-vintage-engine
            
        
    

3、编写配置文件 application.yml

# DataSource Config
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatisplus
    username: root
    password: 123

4、在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 mapper 文件夹

@MapperScan("com.mybatis.study.mapper")
@SpringBootApplication
public class MybatisPlusStudyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusStudyApplication.class, args);
    }
}

5、编写 pojo 类和 mapper 接口

pojo 类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

mapper 接口

public interface UserMapper extends BaseMapper {}

6、运行测试

测试类

@SpringBootTest
class MybatisPlusStudyApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads() {
        List users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
}

运行结果

MyBatis-Plus 学习笔记_第2张图片

配置 Spring 日志

导入 Log4J 日志的坐标


    log4j
    log4j
    ${log4j.version}


    org.slf4j
    slf4j-api
    ${slf4j.version}


    org.slf4j
    slf4j-log4j12
    ${slf4j.version}

编写 log4j 的配置文件

log4j.rootLogger=DEBUG,Console

#Console  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n  

log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.springframework=ERROR
#这个需要
log4j.logger.log4jdbc.debug=ERROR
log4j.logger.com.gk.mapper=ERROR

log4j.logger.jdbc.audit=ERROR
log4j.logger.jdbc.resultset=ERROR
#这个打印SQL语句非常重要
log4j.logger.jdbc.sqlonly=DEBUG
log4j.logger.jdbc.sqltiming=ERROR
log4j.logger.jdbc.connection=FATAL

配置 Spring Boot 日志

在 Spring Boot 中配置日志(编写配置文件 application.yml

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

运行程序

MyBatis-Plus 学习笔记_第3张图片

MyBatis-Plus 常用注解

@TableName

  • 描述:表名注解
属性 类型 必须指定 默认值 描述
value String "" 表名
schema String "" schema
keepGlobalPrefix boolean false 是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMap String "" xml 中 resultMap 的 id
autoResultMap boolean false 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)

@TableId

  • 描述:主键注解
属性 类型 必须指定 默认值 描述
value String "" 主键字段名
type Enum IdType.NONE 主键类型

IdType

描述
AUTO 数据库ID自增
NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT insert前自行set主键值
ASSIGN_ID 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID 分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER 分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID 32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR 分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

@TableField

  • 描述:字段注解(非主键)
属性 类型 必须指定 默认值 描述
value String "" 字段名
el String "" 映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
exist boolean true 是否为数据库表字段
condition String "" 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考
update String "" 字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)
insertStrategy Enum N DEFAULT 举例:NOT_NULL: insert into table_a(column) values (#{columnProperty})
updateStrategy Enum N DEFAULT 举例:IGNORED: update table_a set column=#{columnProperty}
whereStrategy Enum N DEFAULT 举例:NOT_EMPTY: where column=#{columnProperty}
fill Enum FieldFill.DEFAULT 字段自动填充策略
select boolean true 是否进行 select 查询
keepGlobalFormat boolean false 是否保持使用全局的 format 进行处理
jdbcType JdbcType JdbcType.UNDEFINED JDBC类型 (该默认值不代表会按照该值生效)
typeHandler Class UnknownTypeHandler.class 类型处理器 (该默认值不代表会按照该值生效)
numericScale String "" 指定小数点后保留的位数

FieldStrategy

描述
IGNORED 忽略判断
NOT_NULL 非NULL判断
NOT_EMPTY 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
DEFAULT 追随全局配置

FieldFill

描述
DEFAULT 默认不处理
INSERT 插入时填充字段
UPDATE 更新时填充字段
INSERT_UPDATE 插入和更新时填充字段

@Version

  • 描述:乐观锁注解、标记 @Verison 在字段上

@EnumValue

  • 描述:通枚举类注解(注解在枚举字段上)

@TableLogic

  • 描述:表字段逻辑处理注解(逻辑删除)
属性 类型 必须指定 默认值 描述
value String "" 逻辑未删除值
delval String "" 逻辑删除值

@SqlParser

  • 描述:租户注解,支持method上以及mapper接口上
属性 类型 必须指定 默认值 描述
filter boolean false true: 表示过滤SQL解析,即不会进入ISqlParser解析链,否则会进解析链并追加例如tenant_id等条件

@KeySequence

  • 描述:序列主键策略 oracle
  • 属性:value、resultMap
属性 类型 必须指定 默认值 描述
value String "" 序列名
clazz Class Long.class id的类型, 可以指定String.class,这样返回的Sequence值是字符串"1"

常见 CRUD 操作及扩展

Spring Boot 基本操作

前期准备步骤参见[使用 Spring Boot 步骤](#使用 Spring Boot 步骤)

插入操作

简单的插入操作

@Test
void insertTest(){
    User user = new User();
    user.setName("Mybatis");
    user.setAge(11);
    user.setEmail("[email protected]");
    int insert = userMapper.insert(user);
    System.out.println(insert);
}

运行结果

由于我们在插入操作时并没有指定 user 表的主键,但是查询数据库后发现 MyBatis-Plus 帮我们自动生成了主键。这是 MyBatis-Plus 的主键生成策略!

MyBatis-Plus 学习笔记_第4张图片
主键生成策略

默认 ID_WORKER 全局唯一 ID,在 MyBatis-Plus 3.3.0 版本后被 ASSIGN_ID 代替,详情见 MyBatis-Plus 常用注解-IdType

雪花算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生4096 个ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一!

配置主键自增策略

  1. 在实体类的主键上加上 @TableId(type =IdType.AUTO)

  2. 将数据库中的主键字段设置为自增长

    ALTER TABLE USER CHANGE id id BIGINT AUTO_INCREMENT 
    
MyBatis-Plus 学习笔记_第5张图片
  1. 测试插入
MyBatis-Plus 学习笔记_第6张图片

其余字段详情见 MyBatis-Plus 常用注解-IdType

更新操作

简单的更新操作

@Test
void updateTest() {
    User user = User.builder()
        .id(5L)
        .name("Updated")
        .age(99)
        .build();
    userMapper.updateById(user);
}
自动填充

阿里开发手册:所有的数据库表基本都需要配置上:gmt_create(create_time)、gmt_update(update_time) 并且实现自动化

在工作中不允许我们修改数据库,此处仅为演示

方式一:使用数据库级别完成

  1. 在数据表中新增字段 create_timeupdate_time
ALTER TABLE USER 
ADD create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';
ALTER TABLE USER ADD update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间';
MyBatis-Plus 学习笔记_第7张图片
  1. 在实体类中新增属性

    private Date createTime;
    private Date updateTime;
    
  2. 执行更新操作

    @Test
    void updateTest() {
        User user = User.builder()
            .id(4L)
            .name("UpdatedTime")
            .age(55)
            .build();
        userMapper.updateById(user);
    }
    
  1. 更新查看结果

    更新前

MyBatis-Plus 学习笔记_第8张图片

更新后

MyBatis-Plus 学习笔记_第9张图片

方式二:使用代码完成

  1. 将数据表的默认值和更新操作删除

    ALTER TABLE USER
      CHANGE create_time create_time DATETIME NULL COMMENT '创建时间',
      CHANGE update_time update_time DATETIME NULL COMMENT '修改时间';
    
  2. 在实体类上增加注解

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    
  3. 编写处理器处理注解

    @Slf4j
    @Component
    public class MyDateObjectHandler implements MetaObjectHandler {
        /**
         * 插入时的策略
         * @param metaObject 源数据对象
         */
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("start insert fill......");
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    
        /**
         * 更新时的策略
         * @param metaObject 源数据对象
         */
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("start update fill......");
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    }
    
  1. 执行更新操作
MyBatis-Plus 学习笔记_第10张图片
乐观锁

乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论做什么都不上锁!如果出现了问题,再次更新值测试。

悲观锁:顾名思义十分悲观,它总是认为会出现问题,无论做什么都上锁!再去进行操作。

乐观锁实现方式:

  • 取出记录时,获取当前的 version
  • 更新时,带上这个 version
  • 执行更新时, update xxx set version = newVersion where version = oldVersion
  • 如果 version 不正确,则更新失败
乐观锁:1、先查询,获得版本号 version = 1
-- A
update user set name = "test", version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候version = 2,会导致A 修改失败!
update user set name = "test", version = version + 1
where id = 2 and version = 1

乐观锁的使用

  1. 在数据库中新增 version 字段

    ALTER TABLE USER ADD VERSION INT DEFAULT 1 COMMENT '版本号';
    
  1. 在实体类中增加 version 字段

    @Version
    private Integer version;
    
  2. 注册组件

    @MapperScan("com.hsh.study.mapper")
    @EnableTransactionManagement
    @Configuration
    public class MyBatisPlusConfig {
        /**
         * 注册乐观锁插件
         * @return 实例
         */
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor(){
            return new OptimisticLockerInterceptor();
        }
    }
    
  1. 进行测试

    测试方法

    @Test
    void optimisticLockerTest() {
        User user = userMapper.selectById(1L);
        user.setName("lockedTest");
        user.setEmail("[email protected]");
        userMapper.updateById(user);
    }
    

    测试结果

删除操作

删除操作常见的三种方式

/**
 * 根据 id 删除
 */
@Test
void deleteTest(){
    userMapper.deleteById(1255372915881406466L);
}
/**
 * 通过 Id 集合进行删除
 */
@Test
void deleteIdsTest(){
    userMapper.deleteBatchIds(Arrays.asList(1255373036727685122L,1255373036727685123L));
}
/**
 * 通过 Map 来删除
 */
@Test
void deleteMapTest(){
    Map map = new HashMap<>();
    map.put("name","张三");
    userMapper.deleteByMap(map);
}
逻辑删除

逻辑删除:通过一个标记表示此条数据已被删除,不会再数据库中直接删除数据!deleted = 0 -> deleted = 1

物理删除:从数据库中直接删除

1、修改数据库,添加 deleted 字段

alter table `user` add deleted int default 0 comment '逻辑删除';

2、在实体类中添加 deleted 字段

  1. 在配置文件 application.yml 中加入配置

    # 配置 MyBatis-Plus
    mybatis-plus:
      configuration:
        # 配置日志
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      # 配置逻辑删除
      global-config:
        db-config:
          logic-delete-value: 1
          logic-not-delete-value: 0
    
  2. 在实体类上添加 @TableLogic 注解

    @TableLogic
    private Integer deleted;
    

4、测试删除

MyBatis-Plus 学习笔记_第11张图片

查看数据库

MyBatis-Plus 学习笔记_第12张图片

查询操作

常见的查询操作

@Test
void test1(){
    List users = userMapper.selectList(null);
    users.forEach(System.out::println);
}
@Test
void test2(){
    User user = userMapper.selectById(3L);
    System.out.println(user);
}
@Test
void test3(){
    List users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 1255379859656523778L));
    // 查询不到 1255379859656523778L 是因为之前被逻辑删除了!
    users.forEach(System.out::println);
}
@Test
void test4(){
    HashMap map = new HashMap<>();
    map.put("email","[email protected]");
    List users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}
分页查询

MyBatis-Plus 中内置了分页插件

1、配置分页插件

/**
 * 分页插件
 * @return 实例
 */
@Bean
public PaginationInterceptor paginationInterceptor(){
    return new PaginationInterceptor();
}

2、使用

@Test
void pageLimitTest(){
    /* new Page(current,size)
     * current:当前页
     * size:每页大小
     */
    Page page = new Page<>(1,5);
    // 执行分页查询 自动回写到 page 对象中
    userMapper.selectPage(page, null);
    page.getRecords().forEach(System.out::println);
    System.out.println(page.getTotal());
}

Spring 基本操作

前期准备步骤参见[使用 Spring 步骤](#使用 Spring 步骤)

插入操作

简单的插入操作

@Test
public void insertTest(){
    User user = User.builder()
        .name("hhh")
        .age(112)
        .email("[email protected]")
        .build();
    userMapper.insert(user);
}

运行结果

更新操作

简单的更新操作

@Test
void updateTest() {
    User user = User.builder()
        .id(1257194050558160897L)
        .name("1122")
        .age(36)
        .build();
    userMapper.updateById(user);
}
自动填充策略

阿里开发手册:所有的数据库表基本都需要配置上:gmt_create(create_time)、gmt_update(update_time) 并且实现自动化

方式一:使用数据库级别完成 参考 Spring Boot 中的自动填充,此处不做演示

方式二:使用代码完成

  1. 将数据表的默认值和更新操作删除

    ALTER TABLE USER
      CHANGE create_time create_time DATETIME NULL COMMENT '创建时间',
      CHANGE update_time update_time DATETIME NULL COMMENT '修改时间';
    
  2. 在实体类上增加注解

    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    
  3. 编写处理器处理注解

    @Slf4j
    @Component
    public class MyDateObjectHandler implements MetaObjectHandler {
        /**
         * 插入时的策略
         * @param metaObject 源数据对象
         */
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("start insert fill......");
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    
        /**
         * 更新时的策略
         * @param metaObject 源数据对象
         */
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("start update fill......");
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    }
    
  4. 编写 applicationContext.xml 配置文件

    
    
        
            
            
        
    
    
    
        
        
    
    
  1. 执行更新操作
MyBatis-Plus 学习笔记_第13张图片
乐观锁

乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论做什么都不上锁!如果出现了问题,再次更新值测试。

悲观锁:顾名思义十分悲观,它总是认为会出现问题,无论做什么都上锁!再去进行操作。

乐观锁实现方式:

  • 取出记录时,获取当前的 version
  • 更新时,带上这个 version
  • 执行更新时, update xxx set version = newVersion where version = oldVersion
  • 如果 version 不正确,则更新失败

乐观锁的使用

  1. 在数据库中新增 version 字段

    ALTER TABLE USER ADD VERSION INT DEFAULT 1 COMMENT '版本号';
    
  2. 在实体类中增加 version 字段

    @Version
    private Integer version;
    
  3. 注册组件,配置 applicationContext.xml 配置文件

    
    
        
        
        
        
        
        
            
                
                
            
        
    
    
  4. 进行测试

    测试方法

    @Test
    public void optimisticLockerTest() {
        User user = userMapper.selectById(1257194050558160897L);
        user.setName("lockedTest");
        user.setEmail("[email protected]");
        userMapper.updateById(user);
    }
    

    测试结果

MyBatis-Plus 学习笔记_第14张图片

删除操作

删除操作常见的三种方式

/**
 * 根据 id 删除
 */
@Test
void deleteTest(){
    userMapper.deleteById(1255372915881406466L);
}
/**
 * 通过 Id 集合进行删除
 */
@Test
void deleteIdsTest(){
    userMapper.deleteBatchIds(Arrays.asList(1255373036727685122L,1255373036727685123L));
}
/**
 * 通过 Map 来删除
 */
@Test
void deleteMapTest(){
    Map map = new HashMap<>();
    map.put("name","张三");
    userMapper.deleteByMap(map);
}
逻辑删除

逻辑删除:通过一个标记表示此条数据已被删除,不会再数据库中直接删除数据!deleted = 0 -> deleted = 1

物理删除:从数据库中直接删除

1、修改数据库,添加 deleted 字段

alter table `user` add deleted int default 0 comment '逻辑删除';

2、在实体类中添加 deleted 字段

  1. 在配置文件 applicationContext.xml 中加入配置

    
    
        
        
        
             
        
        
        
            
                
                
            
        
    
    
    
        
        
    
    
  2. 在实体类上添加 @TableLogic 注解

    @TableLogic
    private Integer deleted;
    

4、测试删除

查看数据库

MyBatis-Plus 学习笔记_第15张图片

查询操作

常见的查询操作

@Test
void test1(){
    List users = userMapper.selectList(null);
    users.forEach(System.out::println);
}
@Test
void test2(){
    User user = userMapper.selectById(3L);
    System.out.println(user);
}
@Test
void test3(){
    List users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 1255379859656523778L));
    // 查询不到 1255379859656523778L 是因为之前被逻辑删除了!
    users.forEach(System.out::println);
}
@Test
void test4(){
    HashMap map = new HashMap<>();
    map.put("email","[email protected]");
    List users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}
分页查询

MyBatis-Plus 中内置了分页插件

1、配置分页插件



    
    
    
        
            
            
        
    

2、使用

@Test
void pageLimitTest(){
    /* new Page(current,size)
     * current:当前页
     * size:每页大小
     */
    Page page = new Page<>(1,5);
    // 执行分页查询 自动回写到 page 对象中
    userMapper.selectPage(page, null);
    page.getRecords().forEach(System.out::println);
    System.out.println(page.getTotal());
}
MyBatis-Plus 学习笔记_第16张图片

扩展: Wrapper 的使用

当我们需要写一些复杂 SQL 语句时,可以使用 Wrapper 代替,所用 Wrapper 参数解释参见 条件构造器

下面列举常用 Wrapper 及其使用结果

allEq

allEq -> 全部相等或个别 isNull

@Test
void allEqTest(){
    QueryWrapper wrapper = new QueryWrapper<>();
    Map map = new HashMap<>();
    map.put("name","张三");
    map.put("age",null);
    wrapper.allEq(map);
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}
MyBatis-Plus 学习笔记_第17张图片

eq

eq -> 相等(用于判断一个条件时)

@Test
void eqTest(){
    wrapper.eq("email","[email protected]");
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}
MyBatis-Plus 学习笔记_第18张图片

inSql

有两种不同的用法:

  1. inSql("age","1,2,3,4,5") -> age IN (1,2,3,4,5)

  2. inSql("id","select id from user where id < 5") -> id IN (SELECT id FROM user WHERE id < 5)

@Test
void inSqlTest1(){
    wrapper.inSql("age","10,11,20");
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

@Test
void inSqlTest2(){
    wrapper.inSql("id","select id from user where id < 10");
    List users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}
MyBatis-Plus 学习笔记_第19张图片
MyBatis-Plus 学习笔记_第20张图片

其余常见方法参见如下映射表

方法名 数据库名 作用
ne <> 不等于
gt > 大于
ge >= 大于等于
lt < 小于
le <= 小于等于
between BETWEEN 值1 AND 值2 在值 1 和值 2 之间
notBetween NOT BETWEEN 值1 AND 值2 不在值 1 和值 2 之间
like / notLike LIKE '%值%' / NOT LIKE '值' 模糊搜索
likeLeft / likeRight LIKE '%值' / LIKE '值%' 左右模糊匹配
isNull / isNotNull IS NULL / IS NOT NULL 是否为空
in / notIn IN (值1,2...) / NOT IN (值1,2...) 是否在集合中
inSql / notInSql 见例子 子查询或查询集合
groupBy GROUP BY 字段 根据字段分组
orderByAsc / orderByDesc ORDER BY 字段 ASC / ORDER BY 字段 DESC 升序排序 / 降序排序
其余详细字段参见官方文档 官方文档 其余详细字段参见官方文档

你可能感兴趣的:(MyBatis-Plus 学习笔记)