MyBatisPlus学习笔记

MyBatisPlus官方文档:https://baomidou.com/

注:MyBatisPlus 3.0.5版本和3.5.2版本部分配置(MyBatisPlusConfig)会有所不同

1. MyBatisPlus概述

img

Mybatis-Plus(简称MP)是 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

2. 快速入门

实现步骤:

  1. 创建数据库mybatis_plus

  2. 创建User表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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)
    );
    1
    2
    3
    4
    5
    6
    7
    8
    DELETE FROM user;

    INSERT INTO user (id, name, age, email) VALUES
    (1, 'Jone', 18, 'test1@baomidou.com'),
    (2, 'Jack', 20, 'test2@baomidou.com'),
    (3, 'Tom', 28, 'test3@baomidou.com'),
    (4, 'Sandy', 21, 'test4@baomidou.com'),
    (5, 'Billie', 24, 'test5@baomidou.com');
  3. 导入mybatisplus依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
    </dependency>
  4. 连接数据库配置

    1
    2
    3
    4
    5
    #数据库连接配置
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  5. 编写实体类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package com.study.pojo;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
    }
  6. 编写实体类对应的mapper接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package com.study.mapper;

    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.study.pojo.User;
    import org.springframework.stereotype.Repository;

    @Repository //代表持久层
    public interface UserMapper extends BaseMapper<User> {
    //继承了BaseMapper接口,所有的CRUD都已经完成了
    }
  7. 在主启动类添加@MapperScan注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package com.study;

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

    @SpringBootApplication
    @MapperScan("com.study.mapper") //扫描mapper包下的所有接口
    public class MyBatisPlusApplication {

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

    }
  8. 进行Test测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @SpringBootTest
    class MyBatisPlusApplicationTests {

    @Autowired
    private UserMapper userMapper; //继承了BaseMapper,所有的方法都来自父类
    @Test
    void contextLoads() {
    //查询全部用户,参数是一个wrapper条件构造器
    List<User> userList = userMapper.selectList(null);
    userList.forEach(System.out::println);
    }

    }
  9. 测试结果

    QQ截图20221104192116

3. 配置日志

所有的sql是不可见的,可以通过配置日志知道sql是怎么执行的

1
2
#配置日志  log-impl:日志实现
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

QQ截图20221104192604

4. 插入操作

4.1 插入操作

1
2
3
4
5
6
7
8
9
10
@Test
public void insertTest(){
User user = new User();
user.setName("林慕椿");
user.setAge(18);
user.setEmail("2746200911@qq.com");
int result = userMapper.insert(user); //自动生成id
System.out.println(result); //输出受影响的行数
System.out.println(user); //id会自动回填
}

QQ截图20221104194002

数据库插入的id的默认值为:全局的唯—id

4.2 主键生成策略

雪花算法:

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

配置主键自增:

  1. 实体类字段上配置 @TableId(type = IdType.AUTO)

    1
    2
    3
    4
    5
    6
    7
    public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    }
  2. 数据库字段一定是自增

  3. 测试

5. 更新操作

5.1 更新操作

1
2
3
4
5
6
7
8
9
10
@Test
public void updateTest(){
User user = new User();
user.setId(2L); //通过条件自动拼接动态Sql
user.setName("admin");
user.setAge(18);
user.setEmail("updateTest2@baomidou.com");
int i = userMapper.updateById(user); //updateById,但是参数是个user
System.out.println(i);
}

QQ截图20221104195421

5.2 自动填充

创建时间、更改时间! 这些操作一般都是自动化完成,我们不希望手动更新

阿里巴巴开发手册︰几乎所有的表都要配置 gmt_create、gmt_modified !而且需要自动化

方式一:数据库级别(工作中不允许修改数据库级别)

  1. 在表中增加字段:create_time,update_time

  2. 再次测试插入或更新方法,我们需要在实体类中同步

    1
    2
    private Date createTime;//驼峰命名
    private Date updateTime;
  3. 测试

    执行update操作后

    QQ截图20221104200310

方式二:代码级别

  1. 删除数据库的默认值,更新操作

  2. 实体类字段属性上需要增加注解

    1
    2
    3
    4
    @TableField(fill = FieldFill.INSERT)  //插入时填充字段
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时填充字段
    private Date updateTime;
  3. 编写处理器来处理这个注解即可

    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
    package com.study.reggie.common;

    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.sql.Date;
    import java.time.LocalDateTime;

    /*
    * 自定义元数据对象处理器(自动填充配置)
    * @author linmuchun
    * @date 2022/11/6 16:29
    */
    @Slf4j
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
    /*
    * 插入操作自动填充
    * @author linmuchun
    * @date 2022/11/6 16:18
    */
    @Override
    public void insertFill(MetaObject metaObject) {
    log.info("insert公共字段自动填充...");
    log.info(metaObject.toString());
    metaObject.setValue("createTime", LocalDateTime.now());
    metaObject.setValue("updateTime",LocalDateTime.now());
    metaObject.setValue("createUser",BaseContext.getCurrentId());
    metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }

    /*
    * 更新操作自动填充
    * @author linmuchun
    * @date 2022/11/6 16:18
    */
    @Override
    public void updateFill(MetaObject metaObject) {
    log.info("update公共字段自动填充...");
    log.info(metaObject.toString());
    metaObject.setValue("updateTime",LocalDateTime.now());
    metaObject.setValue("updateUser",BaseContext.getCurrentId());
    }
    }

    BaseContext.java

    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
    package com.study.reggie.common;

    /*
    * 基于ThreadLocal封装工具类,用户保存和获取当前用户登录的id
    * @author linmuchun
    * @date 2022/11/6 16:49
    */
    public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    /*
    * 设置值
    * @author linmuchun
    * @date 2022/11/6 17:03
    */
    public static void setCurrentId(Long id){
    threadLocal.set(id);
    }

    /*
    * 获取值
    * @author linmuchun
    * @date 2022/11/6 17:03
    */
    public static Long getCurrentId(){
    return threadLocal.get();
    }
    }

    LoginCheckFilter.java

    1
    2
    3
    //设置empId
    Long empId = (Long) request.getSession().getAttribute("employee");
    BaseContext.setCurrentId(empId);
  4. 测试

5.3 乐观锁

乐观锁:乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。

因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据:如果别人修改了数据则放弃操作,否则执行操作。

悲观锁:悲观锁在操作数据时比较悲观,认为别人会同时修改数据。

因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时,set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

MyBatis-Plus乐观锁插件实现:

  1. 给数据库中增加version字段

  2. 实体类加对应的字段

    1
    2
    @Version//乐观锁version注解
    private Integer version;
  3. 注册组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //扫描mapper文件夹
    @MapperScan("com.study.mapper")//交给mybatis做的,可以让这个配置类做扫描
    @EnableTransactionManagement//自动管理事务
    @Configuration//配置类
    public class MyBatisPlusConfig {
    //注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
    return new OptimisticLockerInterceptor();
    }
    }
  4. 测试

    单线程下:成功

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test//测试乐观锁成功
    public void testOptimisticLocker1(){
    //1、查询用户信息
    User user = userMapper.selectById(1L);
    //2、修改用户信息
    user.setAge(18);
    user.setEmail("2746200911@qq.com");
    //3、执行更新操作
    userMapper.updateById(user);
    }

    多线程下:失败

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Test//测试乐观锁失败  多线程下
    public void testOptimisticLocker2(){
    //线程1
    User user1 = userMapper.selectById(1L);
    user1.setAge(1);
    user1.setEmail("2746200911@qq.com");
    //模拟另外一个线程执行了插队操作
    User user2 = userMapper.selectById(1L);
    user2.setAge(2);
    user2.setEmail("2746200911@qq.com");
    userMapper.updateById(user2);
    //自旋锁来多次尝试提交!
    userMapper.updateById(user1);//如果没有乐观锁就会覆盖插队线程的值
    }

6. 查询操作

6.1 查询操作

通过id查询单个用户

1
2
3
4
5
6
7
8
9
10
/*
* 通过id查询单个用户
* @author linmuchun
* @date 2022/11/4 20:14
*/
@Test
public void selectTest(){
User user = userMapper.selectById(2L);
System.out.println(user);
}

测试结果:

QQ截图20221104201743

通过id查询多个用户

1
2
3
4
5
6
7
8
9
10
/*
* 通过id查询多个用户
* @author linmuchun
* @date 2022/11/4 20:18
*/
@Test
public void selectTest2(){
List<User> userList = userMapper.selectBatchIds(Arrays.asList(1L,2L,3L));
userList.forEach(System.out::println);
}

测试结果:

QQ截图20221104202250

条件查询 通过map封装

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* 条件查询 通过map封装
* @author linmuchun
* @date 2022/11/4 20:26
*/
@Test
public void selectTest3(){
HashMap<String,Object> map = new HashMap<>();
map.put("name","林慕椿");
map.put("age",18);
List<User> userList = userMapper.selectByMap(map);
userList.forEach(System.out::println);
}

测试结果:

QQ截图20221104203031

6.2 分页查询

分页查询的方式:

  • 原始的limit分页
  • pageHelper第三方插件
  • MybatisPlus内置分页插件

分页查询的使用:

  1. 配置拦截器组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package com.study.reggie.config;

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

    /*
    * 配置MybatisPlus分页插件
    * @author linmuchun
    * @date 2022/11/3 20:07
    */
    @Configuration
    public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
    MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
    mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
    return mybatisPlusInterceptor;
    }
    }
  2. 直接使用page对象即可

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /*
    * 员工信息分页查询
    * @author linmuchun
    * @date 2022/11/3 20:12
    */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name){
    log.info("page = {}, pageSize = {}, name = {}",page, pageSize, name);

    //构造分页构造器
    Page pageInfo = new Page(page,pageSize);

    //构造条件构造器
    LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();
    //添加过滤条件
    queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
    //添加排序条件
    queryWrapper.orderByDesc(Employee::getUpdateTime);

    //执行查询
    employeeService.page(pageInfo,queryWrapper);

    return R.success(pageInfo);
    }

7. 删除操作

7.1 删除操作

通过Id删除单个用户

1
2
3
4
@Test
public void deleteTest(){
userMapper.deleteById(6L);
}

测试结果:

QQ截图20221104210633

通过Id删除多个用户

1
2
3
4
@Test
public void deleteTest2(){
userMapper.deleteBatchIds(Arrays.asList(7L,8L));
}

测试结果:

QQ截图20221104210743

通过条件删除用户

1
2
3
4
5
6
7
@Test
public void deleteTest3(){
HashMap<String,Object> map = new HashMap<>();
map.put("name","test04");
map.put("age",24);
userMapper.deleteByMap(map);
}

测试结果:

QQ截图20221104210844

7.2 逻辑删除

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

逻辑删除:在数据库中没有被删除,而是通过一个变量来使他失效! deleted=0 ==> deleted=1

管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!

实现步骤:

  1. 在数据表中增加一个deleted字段

  2. 实体类中添加对应属性

    1
    2
    @TableLogic//逻辑删除注解
    private Integer deleted;
  3. 配置组件

    1
    2
    3
    4
    5
    //逻辑删除组件
    @Bean
    public ISqlInjector sqlInjector(){
    return new LogicSqlInjector();
    }
    1
    2
    3
    #配置逻辑删除  没删除的为0 删除的为1
    mybatis-plus.global-config.db-config.logic-delete-value=1
    mybatis-plus.global-config.db-config.logic-not-delete-value=0
  4. 测试

    发现: 记录还在,deleted变为1

    再次测试查询被删除的用户,发现查询为空

8. 性能分析插件

在平时的开发中,会遇到一些满Sql。测试、druid···

MybatisPlus也提供了性能分析插件,如果超过这个时间就停止运行。

性能分析拦截器作用:用于输出每条sql语句及其执行时间

实现步骤:

  1. 在SpringBoot中配置环境为dev或test环境

    1
    2
    #设置开发环境
    spring.profiles.active=dev
  2. 导入插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
     //性能分析插件
    @Bean
    @Profile({"dev","test"})//设置dev开发、test测试 环境开启 保证我们的效率
    public PerformanceInterceptor performanceInterceptor(){
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    performanceInterceptor.setMaxTime(100);//设置sql最大执行时间*ms,如果超过了则不执行
    performanceInterceptor.setFormat(true);//开启sql格式化
    return performanceInterceptor;
    }
  3. 测试使用

    1
    2
    3
    4
    5
    @Test
    void contextLoads() {
    List<User> userList = userMapper.selectList(null);
    userList.forEach(System.out::println);
    }
  4. 测试

    mybatisplus-01

9. 条件构造器

条件构造器就是可以帮助我们使用面向对象的方式实现数据库操作的where条件,在MyBatis-Plus中将它封装成了一个Wrapper对象,在使用时我们创建条件构造器对象。Wrapper对象的体系的结构大致如下:

1
2
3
4
5
6
7
Wrapper  条件构造抽象类
-- AbstractWrapper 查询条件封装,用于生成 sql 中的 where 语句。
-- QueryWrapper Entity 对象封装操作类,用于查询。
-- UpdateWrapper Update 条件封装操作类,用于更新。
-- AbstractLambdaWrapper 使用 Lambda 表达式封装 wrapper
-- LambdaQueryWrapper 使用 Lambda 语法封装条件,用于查询。
-- LambdaUpdateWrapper 使用 Lambda 语法封装条件,用于更新。

条件构造器测试1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
* 查询name不为空,email不为空,age大于18的用户
* @author linmuchun
* @date 2022/11/4 21:34
*/
@Test
public void wrapperTest(){
QueryWrapper<User> wrapper = new QueryWrapper();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age",18);
//参数是一个wrapper条件构造器
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}

测试结果:

QQ截图20221104214034

条件构造器测试2:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* 查询name="林慕椿"的用户
* @author linmuchun
* @date 2022/11/4 21:41
*/
@Test
public void wrapperTest2(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","林慕椿");
//查询一个数据,若出现多个结果使用list或map,否则会报错
User user = userMapper.selectOne(wrapper);
System.out.println(user);
}

测试结果:

QQ截图20221104214533

条件构造器测试3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
* 查询age在10-20之间的用户
* @author linmuchun
* @date 2022/11/4 21:46
*/
@Test
public void wrapperTest3(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",10,20);
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
//输出查询的数量selectCount
Long count = userMapper.selectCount(wrapper);
System.out.println("查询数量=>"+count);

}

测试结果:

QQ截图20221104215344

条件构造器测试4:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
* 模糊查询
* @author linmuchun
* @date 2022/11/4 21:54
*/
@Test
public void wrapperTest4(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//likeRight:t% likeLeft:%t
wrapper.notLike("name","0")
.likeRight("email","t");
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}

测试结果:

QQ截图20221104220135

条件构造器测试5:

1
2
3
4
5
6
7
8
9
10
11
12
/*
* 嵌套查询
* @author linmuchun
* @date 2022/11/4 22:02
*/
@Test
public void wrapperTest5(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id","select id form user where id<3");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}

条件构造器测试6:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
* 通过id进行排序
* @author linmuchun
* @date 2022/11/4 22:17
*/
@Test
public void wrapperTest6(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
//Desc:降序 Asc:升序
wrapper.orderByDesc("id");
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}

测试结果:

QQ截图20221104222115

10. 代码生成器

代码生成器:

MyBatis-Plus CodeGenerator 代码自动生成器,可以根据使用者的配置,去数据库中根据每一个数据表自动生成对应的 Controller、Service、ServiceImpl、Mapper、Entity 等繁琐且没有技术含量的事情,提高开发效率。

代码生成器的使用:

导入依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!--模板引擎 依赖:mybatis-plus代码生成的时候报异常-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<!--配置ApiModel在实体类中不生效-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>spring-boot-starter-swagger</artifactId>
<version>1.5.1.RELEASE</version>
</dependency>
<!--freemarker-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<!--beetl-->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
<version>3.3.2.RELEASE</version>
</dependency>

配置:

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.study;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
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.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
//代码自动生成器
public class WskCode {
public static void main(String[] args) {
//我们需要构建一个代码生成器对象
AutoGenerator mpg = new AutoGenerator();
//怎么样去执行,配置策略
//1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");//获取当前目录
gc.setOutputDir(projectPath+"/src/main/java");//输出到哪个目录
gc.setAuthor("wsk");
gc.setOpen(false);
gc.setFileOverride(false);//是否覆盖
gc.setServiceName("%sService");//去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setUrl("jdbc:mysql://localhost:3306/wuye?useSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("study");
pc.setParent("com.wsk");
pc.setEntity("pojo");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("admin","danyuan","building","room");//设置要映射的表名,只需改这里即可
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);//是否使用lombok开启注解
strategy.setLogicDeleteFieldName("deleted");
//自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtUpdate = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtUpdate);
strategy.setTableFillList(tableFills);
//乐观锁配置
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);//开启驼峰命名
strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
mpg.setStrategy(strategy);
mpg.execute();//执行
}
}

MyBatisPlus学习笔记
https://yiqiangshiyia.cn/2022/11/04/MyBatisPlus学习笔记/
作者
一腔诗意啊
发布于
2022年11月4日
许可协议