MyBatisPlus 基础入门

1. 数据库初始化

  1. 创建数据库
  2. 创建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)
    );
  3. 插入数据

    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]');

2. 创建SpringBoot项目

1. 导入依赖

<!--    mp依赖    -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<!--lombok以来-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>

以上依赖中,mp和mysql驱动为必须添加的

2. 添加配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.3.66/mybatisplus_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: oyl
    password: 123123

3. 主类添加扫描注解

@MapperScan("com.oylong.mptest.mapper")   //添加此注解
@SpringBootApplication
public class MpTestApplication {

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

}

4. 创建实体类

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

3. MybatisPlus 使用

1. 创建Mapper接口,继承自BaseMapper

package com.oylong.mptest.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.oylong.mptest.entity.User;

public interface UserMapper extends BaseMapper<User> {
}
//此接口要放在主类扫描注解对应的mapper包下

2. 测试类测试

  1. 注入UserMapper,并且使用userMapper查询所有的用户

    @Autowired
    private UserMapper userMapper;
    
    @Test
    void contextLoads() {
        userMapper.selectList(null).stream().forEach(System.out::println);
    }

image-20200819142751626.png

如图,打印了数据库中的所有数据

  1. 开启详细日志

    控制台打印的数据并不是很详细,不能看到具体的sql语句,添加如下:

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://192.168.3.66/mybatisplus_test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
        username: oyl
        password: 123123
        
    # 添加的配置
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

    再次运行:

image-20200819143345445.png

控制台中打印了详细的sql语句.

3. 主键自增策略

  1. 通过注解设置:

    @Data
    public class User {
        
        //通过此注解设置自增策略
        @TableId(type = IdType.ASSIGN_ID)
        private Long id;
        
        private String name;
        private Integer age;
        private String email;
    }

    可以通过@TableId(type = IdType.xxxxx)这个注解来设置自增策略,MyBatisPlus默认的自增策略为雪花算法,几种自增策略为:

    • IdType.Auto: 表示数据库ID自增,设置为此项需要设置数据库的主键字段为自增
  • IdType.UUID: 表示设置主键ID为UUID

    • IdType.ASSIGN_ID: 表示通过雪花算法设置主键ID
  1. 通过全局配置设置

    mybatis-plus:
      global-config:
        db-config:
          id-type: assign_id

    也可以通过添加如上的配置,来全局统一的配置自增策略

4. CRUD

  1. 查询

image-20200820175018006.png

如上图所示的方法,查询有很多,通常使用较多的就是selectList,selectOne,selectById,selectCount,selectPage这几个,通常会搭配QuerryWrapper这个对象用来进行条件查询,如下代码:

@Test
void selectTest() {
    List<User> users = userMapper.selectList(null);

    for(User user: users) {
        System.out.println(user);
    }

    User user = userMapper.selectById(1);

    System.out.println(user);

    User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("name", "Jack"));

    System.out.println(user1);
}
  1. 插入

    插入操作较为简单,如下:

    User user = new User();
    user.setAge(18);
    user.setEmail("[email protected]");
    user.setName("oyLong");
    
    userMapper.insert(user);
  2. 删除

    删除也比较简单,可以通过querryWrapper对象进行条件删除,也可以通过deleteById通过id来删除

    userMapper.delete(new QueryWrapper<User>().eq("id", 1));
    
    userMapper.deleteById(1);

    以上两种方式都可用于删除

  3. 更新

    更新则通过updeteXXX方法来进行更新

    User user = new User();
    user.setId(1296392290754887684L);   //必须要设置id
    user.setName("oyl");
    user.setAge(22);
    userMapper.updateById(user);

    或者通过querryWrapper来条件查询更新

    User user = new User();
    user.setName("oyl");
    user.setAge(22);
    userMapper.update(user, new QueryWrapper<User>().eq("id", 1296392290754887684L));

    两种方法都可用于更新

5. 返回值

select方法通常返回对应的实体类或者实体类列表,而其他的三个增删改方法则返回影响的行数

6. 自动填充功能

<<阿里巴巴Java开发手册>>中有这样的规范:

【强制】表必备三字段:id, gmt_create, gmt_modified。 说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。gmt_create, gmt_modified 的类型均为 datetime 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新

而在业务中如果执行了更新或者插入操作,通常需要手动设置,比较麻烦,因此可以使用MybatisPlus的自动填充功能,如下:

a. 添加注解

@Data
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;

    private String name;
    private Integer age;
    private String email;

    @TableField(fill = FieldFill.INSERT)
    private Date gmtCreate;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmtModified;
}

如上代码中,在两个时间的属性上面,添加@TableField注解,并且注明填充的时机.

  • FieldFill.INSERT : 在插入时填充
  • FieldFill.UPDATE : 在更新时填充
  • FieldFill.INSERT_UPDATE : 在插入和更新时都填充

b. 实现元对象处理器接口

package com.oylong.mptest.handler;

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

import java.util.Date;

/**
 * @ProjectName: mp-test
 * @Description:
 * @Author: OyLong
 * @Date: 2020/8/20 18:34
 */
@Slf4j
@Component  //别忘记注入spring容器
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("insertFill....");
        this.strictInsertFill(metaObject, "gmtCreate", Date.class, new Date());
        this.strictInsertFill(metaObject, "gmtModified", Date.class, new Date());

    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("updateFill....");
        this.strictInsertFill(metaObject, "gmtModified", Date.class, new Date());
    }
}

这个实现类其中一个需要注意的点就是别忘记了添加@Component注解将此类注入spring容器

4. 测试

接下来进行测试,首先插入一个

image-20200820184628385.png

可以在输出的sql语句上看到,已经成功的自动设置了时间

然后update

image-20200820184825265.png

也可以在输出的sql语句中看到,自动添加了gmt_modified这个字段

7. 分页

  1. 添加MybatisPlus 分页配置

    @Configuration
    public class MPConfig {
        @Bean
        PaginationInterceptor paginationInterceptor(){
            return new PaginationInterceptor();
        }
    }
  2. 通过selectPage方法

    @Test
    void selectTest() {
        Page<User> userPage = userMapper.selectPage(new Page<User>(1, 3), null);
        List<User> records = userPage.getRecords();
        long total = userPage.getTotal();
    }

    如上,可以通过设置selectPage的第一个参数,传入一个Page对象,设置分页的参数,当前页数和每页大小,后面还可以传入一个QueryWrapper对象用于条件查询.可以通过getRecords获得所有的记录,getTotal获得总共的记录数.

  3. 通过selectMapsPage返回Map对象

    我们还可以通过selectMapsPage,这个方法来使返回的列表是一个Map对象,如下

    @Test
    void selectTest() {
        Page<Map<String, Object>> page = new Page(1,3);
        Page<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, null);
    
        List<Map<String, Object>> records = mapPage.getRecords();
        System.out.println(records);
    }

    输出结果:

    [{name=Jack, id=2, age=20, email=[email protected]}, {name=Tom, id=3, age=28, email=[email protected]}, {name=Sandy, id=4, age=21, email=[email protected]}]

8. 逻辑删除

逻辑删除表示并不会真正的在数据库中删除对应的记录,而是将某个特定的字段置为特定的值,然后再查询时通过条件将其过滤.

  1. 先在数据库中添加字段值 idDeleted
  2. 在实体类中通过@TableLogic注解标注此属性

    @TableLogic
    private Integer isDeleted;
    public @interface TableLogic {
    
        /**
         * 默认逻辑未删除值(该值可无、会自动获取全局配置)
         */
        String value() default "";
    
        /**
         * 默认逻辑删除值(该值可无、会自动获取全局配置)
         */
        String delval() default "";
    }

    通过上面的注解源码可以看到,我们可以设置其是否被删除的默认值,如下:

    @TableLogic(value = "0", delval = "1")
    private Integer isDeleted;

    表示未删除时用0表示,删除了用1表示

    也可以通过设置全局配置文件的方式来设置默认值:

    mybatis-plus:
      global-config:
        db-config:
          logic-delete-value: 1
          logic-not-delete-value: 0
  3. 测试

    执行删除时输出的sql

    ==> Preparing: UPDATE user SET is_deleted=1 WHERE id=? AND is_deleted=0
    ==> Parameters: 2(Integer)
    <== Updates: 1

    执行查询时的sql:

    ==> Preparing: SELECT id,name,age,email,gmt_create,gmt_modified,is_deleted FROM user WHERE is_deleted=0
    ==> Parameters:

    可以看到,后面都加上了一个判断,即is_deleted=0来过滤已经被逻辑删除的记录

9.条件构造器

包含以下这些类

  • Wrapper : 条件构造抽象类,最顶端父类
  • AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  • QueryWrapper : 查询条件封装
  • UpdateWrapper : Update 条件封装
  • AbstractLambdaWrapper : 使用Lambda 语法
  • LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper
  • LambdaUpdateWrapper : Lambda 更新封装Wrapper
查询方式说明
setSqlSelect设置 SELECT 查询字段
whereWHERE 语句,拼接 + WHERE 条件
andAND 语句,拼接 + AND 字段=值
andNewAND 语句,拼接 + AND (字段=值)
orOR 语句,拼接 + OR 字段=值
orNewOR 语句,拼接 + OR (字段=值)
eq等于=
allEq基于 map 内容等于=
ne不等于<>
gt大于>
ge大于等于>=
lt小于<
le小于等于<=
like模糊查询 LIKE
notLike模糊查询 NOT LIKE
inIN 查询
notInNOT IN 查询
isNullNULL 值查询
isNotNullIS NOT NULL
groupBy分组 GROUP BY
havingHAVING 关键词
orderBy排序 ORDER BY
orderAscASC 排序 ORDER BY
orderDescDESC 排序 ORDER BY
existsEXISTS 条件语句
notExistsNOT EXISTS 条件语句
betweenBETWEEN 条件语句
notBetweenNOT BETWEEN 条件语句
addFilter自由拼接 SQL
last拼接在最后,例如:last(“LIMIT 1”)

通常使用QuerryWrapper对象的查询方式即可完成大部分的条件查询.

Last modification:August 20, 2020
If you think my article is useful to you, please feel free to appreciate