学习使用 Mybatis Plus 的记录文「不完整」

概述

简单来说,使用它的原因是因为可以省去很多 CRUD 的过程.. 因为它内部已经继承好了~
并且它下面继承了很多强大的功能,包括但不限于:**乐观锁/自动填充/SQL性能分析/逻辑删除/代码生成...等!
本篇文章对于 Mybatis Plus 来说并不完善,当使用到一些功能的时候再来更新文章.

使用Myabtis Plus

Maven

分别导入 Mybatis plus 以及 MySQL 驱动的包!

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

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

数据源

主要的地方在于后面时区的配置,如果不配置的话,时间是错误的!

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

配置

在之前学习 mybatis 中我们知道,我们需要进行扫描 mapper 将其托管给 spring~
我们创建一个配置类. 然后使用 MapperScan 注解进行扫描. 如果还存在其他目录,我们也可以在 mapper 之上使用@mapper 进行声明.


@EnableTransactionManagement
@Configuration
@MapperScan("com.kum.mapper")
public class MybatisPlusConfig { }

自此,简单的配置就 ok 了,别看这里没内容,我们后面还会用到~

创建 Mapper

当然,创建mapper 的前提是创建一个与我们数据库字段相同的实体类!
只需要继承 BaseMapper<实体类> 就完成了...

public interface UserMapper extends BaseMapper<User> {
}

这样..我们就继承了该实体类的全部方法,一些常用的 CRUD 都在其中...

基础的操作

我们创建一个 Test 类进行测试一下.
在之前学习 mybatis 中我们知道,只需要获得 spring 所托管的 Mapper 就可以对其进行操作!
首先要注意的是,如果使用@Autowired 注解,Idea会提示找不到这个类. 不过这个是 idea 的问题,只需要抑制一下警告或者使用@Resource注解.

以下代码便是获得全部数据.其中带有一个Wrapper类型的参数,这个主要是做一些条件判断,我们的目的是获得全部,自然不需要.

    List<User> list = userMapper.selectList(null);
    list.forEach(System.out::print);

插入 insert / 更新 update.. 这里就不再撰述.

条件查询「 Map 与 Wrapper」

实际上二者功能一样,不过 Wrapper 更加灵活一些~

当执行以下代码,我们便只会匹配 map 的 Key(字段) 对应的 Value(值).

    HashMap<String, Object> map = new HashMap<>();
    map.put("email","481326635@qq.com");
    List<User> list = userMapper.selectByMap(map);
    list.forEach(System.out::println);

而通过 Wrapper 可以更灵活的去处理复杂的 sql 语句.
首先我们创建一个 WueryWrapper 对象,然后通过各种方法去 "配置" 这个 Wrapper.以下代码仅是举例,并不只有这些.

    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
            .isNotNull("name")  //name != null
            .like("name","s"); // name like '%s%'

    List<User> list = userMapper.selectList(wrapper);
    list.forEach(System.out::print);

主键策略

一般情况下我们数据表的主键策略都是采用一个 int 值进行一直递增呀之类的. Mybatis Plus 内置了一些主键策略.
我们可以直接使用它内置的.
ASSIGN_ID,它使用了雪花算法+UUID进行创建,它支持 long / integer / string .
ASSIGN_UUID,不带"-"的 UUID,支持 string.
我们只需要对其做一些简单的配置~

配置

我们需要在实体类上增加以下注解,注意实体类 ID 类型和数据库 ID 类型一定要和策略所支持的类型一致!否则报错.

@TableId(type = IdType.ASSIGN_UUID)

自此便可以查看效果了.. 值得记录的是,即使你数据库中设置了主键自增策略,在使用 Mybatis Plus 也是不生效的! 你需要按照上面的方式设置为 IdType.Auto.

自动填充

在阿里巴巴编程手册中写道,每一个数据表都要拥有两个字段,分别是 create_time 和 update_time,分别对应数据的创建时间和修改时间,方便后期进行修改. 我们平常在写这个功能的时候都需要在insert 数据的时候去写. 而 Mybatis Plus 则继承了自动填充的功能.可以省去这些类似需求的过程!

首先我们需要在实体类对应的两个字段加入注解,含义是在什么时候触发. 很显然,这个对应的是插入时.

    @TableField(fill = FieldFill.INSERT)

我们也可以使用 INSERT_UPDATE 作为一直响应,也可以是 UPDATE (更新时响应).

    @TableField(fill = FieldFill.INSERT_UPDATE)

配置

接下里我们只需要创建一个配置类去告诉 Mybatis Plus 我们需要填充什么内容~
我们需要实现MetaObjectHandler中的方法! 并且使用@Component托管给 spring ,Mybatis Plus 会自动使用这个类.


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

    @Override
    public void updateFill(MetaObject metaObject) {

        this.strictInsertFill(metaObject,"updateTime",Date.class,new Date());
   
    }
}

代码实际上很清晰,直接使用this.strictInsertFill(metaObject,数据类型,数据)就可以完成.

分页操作

我们一般分页都是通过 MySQL 的 limit指令 ,Mybatis Plus 中也封装了这样的方法~ 并且更为方便~

配置

在我们前面创建的MybatisConfig类中加入以下方法.

@Bean
public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
    // paginationInterceptor.setOverflow(false);
    // 设置最大单页限制数量,默认 500 条,-1 不受限制
    // paginationInterceptor.setLimit(500);
    // 开启 count 的 join 优化,只针对部分 left join
    paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
    return paginationInterceptor;
}

然后就可以直接使用分页操作了~
创建一个 page 对象,第一个参数是第几页,第二个是每页分几份~ 这样就可以获得 5/6 两个数据.

    Page<User> page = new Page<>(3, 2);
    userMapper.selectPage(page, null);
    page.getRecords().forEach(System.out::println);