springboot+druid+mybatis-plus

具体可查看官方文档 https://baomidou.com/guide 。以下仅为笔记。

目录

    • 快速入门
    • application配置日志
    • 插入操作
    • mybatis-plus提供的主键分配类型
    • 更新操作
    • 自动填充
    • 乐观锁
    • 查询操作
    • 分页查询
    • 删除操作
    • 逻辑删除
    • 性能分析插件
    • 条件查询器Wrapper
    • 代码生成器

快速入门

pom.xml

必要依赖:

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
dependency>

<dependency>
    <groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-boot-starterartifactId>
    <version>3.4.1version>
dependency>

<dependency>
    <groupId>com.alibabagroupId>
    <artifactId>druidartifactId>
    <version>1.2.4version>
dependency>

application配置文件

spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://192.168.72.149:3306/mybatis_plus?userSSL=false&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

注:
如果想使用默认的Hikari数据源,则注释掉pom.xml中的druid依赖和application配置文件中spring.datasource.type

com.mysql.jdbc.Driver 是 mysql-connector-java 5中的
com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6中的,相比mysql-connector-java 5 多了一个时区:serverTimezone,
把数据源配置的url中增加:serverTimezone=GMT%2B8  GMT%2B8表示北京时间东八区

pojo

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

Mapper

@Repository
public interface UserMapper extends BaseMapper<User> {
}

启动类

@SpringBootApplication
@MapperScan("com.jarvis.mptest.Mapper")  //需要将Mapper包下的所有接口扫描到ioc中
public class MptestApplication {
    public static void main(String[] args) {
        SpringApplication.run(MptestApplication.class, args);
    }
}

数据库表

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)                     //注:此时id不是自增的
);

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

测试

@SpringBootTest
class MptestApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    void contextLoads() {
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
}
=====output:
User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)

application配置日志

# 配置日志  StdOutImpl--打印控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

控制台打印日志如下:
springboot+druid+mybatis-plus_第1张图片

插入操作

User user = new User();
user.setName("yyb");
user.setAge(25);
user.setEmail("[email protected]");
int count = userMapper.insert(user);
log.info("插入{}条",count);
log.info("user={}",user);

报错:Could not set property 'id' of 'class com.jarvis.mptest.pojo.User'
with value '1344543840895275009' Cause: java.lang.IllegalArgumentException: 
argument type mismatch   
生成的id为:1344543840895275009,报错提示:将id回存给User的时候类型不匹配
将User的id类型从Integer改为Long,可插入成功,但是id不是自增的,输出:
插入1条
user=User(id=1344563190515642370, name=yyb, age=25, email=yyb97456@gmail.com)

主键生成策略:1. uuid 2. 自增id 3. 雪花算法 4. redis生成 …

雪花算法
SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的

mybatis-plus提供的主键分配类型

3.4.1版本的mybatis-plus的主键生成策略如下
@Getter
public enum IdType {
    //数据库ID自增  该类型请确保数据库设置了ID自增,否则无效
    AUTO(0),
    //未设置主键类型
    NONE(1),
    //手动输入ID  
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    //分配ID (主键类型为number或string) 
    //默认实现类 { com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
    ASSIGN_ID(3),
    //UUID (主键类型为 string)
    //默认实现类 { com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
    ASSIGN_UUID(4),
    
    //不推荐使用, 3.3.0 请使用 ASSIGN_ID
    ID_WORKER(3),
    //不推荐使用, 3.3.0 请使用 ASSIGN_ID
    ID_WORKER_STR(3),
    //不推荐使用, 3.3.0 请使用 ASSIGN_UUID
    UUID(4);

    private final int key;
    IdType(int key) {
        this.key = key;
    }
}

AUTO----自增主键

  1. 需要给数据库表id字段设置为自增
  2. 在pojo上的id属性增加@TableId(type = IdType.AUTO)

INPUT----手动设置id

pojo:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.INPUT)  //需要手动设置id值
    private Integer id;
    ...
}
测试1----不设置id:
@Test
void testInsert(){
    User user = new User();  //未设置id
    user.setName("yyb787");
    user.setAge(25);
    user.setEmail("[email protected]");
    int count = userMapper.insert(user);
    log.info("插入{}条",count);
    log.info("user={}",user);

}
当数据库表id不自增,会报错:Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'id' cannot be null
当数据库表id自增,如果不设置id,则不报错,写入的是自增后的id。

测试2----id重复
@Test
void testInsert(){
    User user = new User(6,"asdf",5,"asdfadsf");
    int count = userMapper.insert(user);
    log.info("插入{}条",count);
    log.info("user={}",user);
}
报错:Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '6' for key 'PRIMARY'

ASSIGN_ID----雪花算法

注:id类型需要改为Long

ASSIGN_UUID----uuid

  1. 数据库表的字段id需要为varchar,长度要长点,不然装不下
  2. 在pojo上的id属性增加@TableId(type = IdType.ASSIGN_UUID),且设置为String类型
  3. 插入的对象id需要为null才能插入uuid
pojo:
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;
测试:
@Test
void testInsert(){
    User user = new User(null,"小王",15,"[email protected]");
    int count = userMapper.insert(user);
    log.info("插入{}条",count);
    log.info("user={}",user);
}

springboot+druid+mybatis-plus_第2张图片

更新操作

updateById:传入的对象某个字段如果为null,则在拼接动态sql的时候该字段被忽略

User user = new User(1,null,null,"[email protected]");
int i = userMapper.updateById(user);
log.info("修改{}条",i);
================
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@559cedee] will not be managed by Spring
==>  Preparing: UPDATE user SET email=? WHERE id=?     //只拼接了email这个非null的字段
==> Parameters: 17816878521@163.com(String), 1(Integer)
<==    Updates: 1

自动填充

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

1. 将pojo的User新增两个字段:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(value = "id",type = IdType.AUTO)
    private Integer Id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT)  //将创建时间在插入时自动填充
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)  //将修改时间在插入和修改操作时自动填充
    private LocalDateTime updateTime;
}

2. 编写处理器来处理注解 ---- 不同版本的MP有不同的填充方法

@Slf4j
@Component
public class PojoMetaObjectHandler implements MetaObjectHandler {
    /**
     * 插入时的填充策略
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //填充的是实体类属性名称,而不是数据库的字段名称
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject,"updateTime",LocalDateTime.class, LocalDateTime.now());
//        // 或者
//        this.strictUpdateFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
//        // 或者
//        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
    /**
     * 更新时的填充策略
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
//        // 或者
//        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
//        // 或者
//        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
}

测试新增数据

@Test
void testInsert(){
    User user = new User();
    user.setName("小王");
    user.setEmail("[email protected]");
    user.setAge(26);
    int count = userMapper.insert(user);
    log.info("插入{}条",count);
    log.info("user={}",user);
}

在这里插入图片描述
测试修改数据

@Test
void testUpdate(){
    User user = new User();
    user.setId(102);
    user.setEmail("[email protected]");
    int i = userMapper.updateById(user);
    log.info("修改{}条",i);
}

springboot+druid+mybatis-plus_第3张图片

乐观锁

乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
说明:
支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
整数类型下 newVersion = oldVersion + 1
newVersion 会回写到 entity 中
仅支持 updateById(id) 与 update(entity, wrapper) 方法
在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

1. 在数据库中增加一个字段version,类型int,默认值设置为1
2. pojo的User增加属性version

    @Version   //乐观锁注解
    private Integer version;

3. 注册乐观锁组件

@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
    @Bean  //新版本(当前测试版本3.4.1)会提示OptimisticLockerInterceptor不推荐使用,但是仍能起作用
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }  
    或:
    @Bean  //新版本(当前测试版本3.4.1)可使用如下方法配置
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

4. 测试乐观锁

1. 先查询,后更新
@Test
void testOptimisticLocker(){
    User user = userMapper.selectById(104);
    System.out.println(user);
    user.setEmail("[email protected]");
    userMapper.updateById(user);
}
==>  Preparing: UPDATE user SET name=?, birth=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?  //加了AND version=?
==> Parameters: 小王(String), 2018-05-01T15:26:09(LocalDateTime), 26(Integer), opop@163.com(String), 2021-01-03T19:20:42(LocalDateTime), 2021-01-03T20:25:16(LocalDateTime), 4(Integer), 104(Integer), 3(Integer)
<==    Updates: 1

2. 直接更新,无法动态拼接AND version=?
@Test
void testOptimisticLocker(){
    User user = new User();
    user.setId(104);
    user.setEmail("[email protected]");
    userMapper.updateById(user);
}
==>  Preparing: UPDATE user SET email=?, update_time=? WHERE id=?   //没有加and version=?
==> Parameters: opuuddop@163.com(String), 2021-01-03T20:25:16.297(LocalDateTime), 104(Integer)
<==    Updates: 1

3. 测试乐观锁失败
@Test
void testOptimisticLocker() throws InterruptedException {
    User user = userMapper.selectById(104);
    System.out.println(user); //User(Id=104, name=小王, birth=2018-05-01T15:26:09, age=26, [email protected], createTime=2021-01-03T19:20:42, updateTime=2021-01-03T20:25:16, version=5)
    Thread.sleep(5000);  //睡眠5s,此时手动去修改数据库中的version为6,导致本次无法update成功
    user.setEmail("[email protected]");
    userMapper.updateById(user);
}
==>  Preparing: UPDATE user SET name=?, birth=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=?
==> Parameters: 小王(String), 2018-05-01T15:26:09(LocalDateTime), 26(Integer), opop@163.com(String), 2021-01-03T19:20:42(LocalDateTime), 2021-01-03T20:25:16(LocalDateTime), 6(Integer), 104(Integer), 5(Integer)
<==    Updates: 0

查询操作

@Test
void testSelect(){
    //根据id查询
    User user = userMapper.selectById(103);  
    //SELECT id,name,birth,age,email,create_time,update_time,version FROM user WHERE id=?
    System.out.println(user);
    //根据id集合批量查询
    List<User> users = userMapper.selectBatchIds(Arrays.asList(103, 104));  
    //SELECT id,name,birth,age,email,create_time,update_time,version FROM user WHERE id IN ( ? , ? )
    users.forEach(System.out::println);
    //按条件查询  map
    HashMap<String,Object> map = new HashMap<>();
    map.put("name","小李");
    map.put("email","[email protected]");
    List<User> users1 = userMapper.selectByMap(map);  
    //SELECT id,name,birth,age,email,create_time,update_time,version FROM user WHERE name = ? AND email = ?
    System.out.println(users1);
    //按条件查询  Wrapper
    QueryWrapper<User> wrapper = new QueryWrapper<User>();
    wrapper.eq("name","小李").eq("email","[email protected]");
    List<User> users2 = userMapper.selectList(wrapper);  
    //SELECT id,name,birth,age,email,create_time,update_time,version FROM user WHERE (name = ? AND email = ?)
    System.out.println(users2);
}

分页查询

1. 注册分页插件 ---- 不同版本的MP有不同的注册方法

@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {
    @Bean  //新版本(当前测试版本3.4.1)会提示PaginationInterceptor 不推荐使用
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }
    或:
    @Bean  //新版本(当前测试版本3.4.1)可使用如下方法配置
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        // 添加分页插件
        PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor();
        // 设置请求的页面大于最大页后操作,true调回到首页,false继续请求。默认false
        pageInterceptor.setOverflow(false);
        // 单页分页条数限制,默认无限制
        pageInterceptor.setMaxLimit(500L);
        // 设置数据库类型
        pageInterceptor.setDbType(DbType.MYSQL);
        interceptor.addInnerInterceptor(pageInterceptor);
        return interceptor;
    }
}

2. 使用Page对象

@Test
void testSelectPage(){
    Page<User> page = new Page<>(2,5);
    //selectPage方法将查询的数据封装到了Page对象的records属性中(该属性是个List),并且返回这个Page对象
    Page<User> page1 = userMapper.selectPage(page, null);  //page1 = page
    long total = page.getTotal();  //getTotal需要在selectPage方法之后才能调用
    System.out.println("total="+total);  
    page.getRecords().forEach(System.out::println);
}
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@29b40b3] will not be managed by Spring
//selectPage一个方法中一共查询两次数据库
//第一次查询:查询总数,并且把查询的总数赋值给Page对象的total属性,所以getTotal需要在selectPage方法之后才能调用
==>  Preparing: SELECT COUNT(*) FROM user
==> Parameters: 
<==    Columns: COUNT(*)
<==        Row: 14
<==      Total: 1
//第二次查询分页数据
==>  Preparing: SELECT id,name,birth,age,email,create_time,update_time,version FROM user LIMIT ?,?
==> Parameters: 5(Long), 5(Long)
<==    Columns: id, name, birth, age, email, create_time, update_time, version
<==        Row: 108, 小王02, 2018-05-01 15:26:09, 26, 17816549851@163.com, 2021-01-04 15:42:45, 2021-01-04 15:42:45, 1
<==        Row: 109, 小王02, 2018-05-01 15:26:09, 26, 17816549851@163.com, 2021-01-04 15:42:45, 2021-01-04 15:42:45, 1
<==        Row: 110, 小王02, 2018-05-01 15:26:09, 26, 17816549851@163.com, 2021-01-04 15:42:45, 2021-01-04 15:42:45, 1
<==        Row: 111, 小王02, 2018-05-01 15:26:09, 26, 17816549851@163.com, 2021-01-04 15:42:45, 2021-01-04 15:42:45, 1
<==        Row: 112, 小王02, 2018-05-01 15:26:09, 26, 17816549851@163.com, 2021-01-04 15:42:45, 2021-01-04 15:42:45, 1
<==      Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@439f2d87]
total=10

删除操作

@Test
void testDelete(){
    userMapper.deleteById(103);
    userMapper.deleteBatchIds(Arrays.asList(104,105,106));
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","小王02");
    userMapper.deleteByMap(map);
}

逻辑删除

通过设置字段值来使得某些记录失效,如is_delete

1. 在数据库的user表中增加is_delete字段,默认值为0
2. 在pojo的User类中增加isDelete属性,类型为Boolean或Integer,并且增加逻辑删除的注解:@TableLogic
3. application文件中配置(新版本写法)

# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

测试

@Test
void testDeleteLogic(){
    userMapper.deleteById(128); 
    //UPDATE user SET is_delete=1 WHERE id=? AND is_delete=0
    User user = userMapper.selectById(128);  
    //SELECT id,name,birth,age,email,create_time,update_time,version,is_delete FROM user WHERE id=? AND is_delete=0  自动拼接了逻辑删除的判断
    System.out.println(user);  //null
}

性能分析插件

在新版本(3.3.0以后)使用p6spy,但该插件有性能损耗,不建议生产环境使用。

条件查询器Wrapper

不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输
1. wrapper 很重
2. 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
3. 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
4. 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至 pr

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

1. pom.xml添加代码生成器依赖

<dependency>
    <groupId>com.baomidougroupId>
    <artifactId>mybatis-plus-generatorartifactId>
    <version>3.4.1version>
dependency>

<dependency>
    <groupId>org.freemarkergroupId>
    <artifactId>freemarkerartifactId>
    <version>2.3.30version>
dependency>

<dependency>
    <groupId>io.springfoxgroupId>
    <artifactId>springfox-swagger2artifactId>
    <version>2.9.2version>
dependency>
<dependency>
    <groupId>io.springfoxgroupId>
    <artifactId>springfox-swagger-uiartifactId>
    <version>2.9.2version>
dependency>

2. 代码生成器

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class CodeGeneratorTest {
    @Test
    void test(){
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // *********************************全局配置*********************************
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");  //获取项目路径
        gc.setOutputDir(projectPath + "/src/main/java");  //设置代码生成路径
        gc.setAuthor("jarvis");
        gc.setOpen(false);  //生成后是否打开文件夹,设置为不打开
        gc.setFileOverride(false);  //设置是否覆盖原来的
        gc.setIdType(IdType.AUTO);  //设置主键生成策略
        gc.setServiceName("%sService"); //去Service的I前缀 无此配置生成的为IUserService
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);

        // *********************************数据源配置*********************************
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://192.168.72.152:3306/mybatis_plus?userSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // *********************************包配置*********************************
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("gmall");
        pc.setParent("com.jarvis");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        // *********************************策略配置*********************************
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("user","order");  //生成哪些表的代码
        strategy.setNaming(NamingStrategy.underline_to_camel);  //下划线转驼峰
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("你自己的父类实体,没有就不用设置!");
        strategy.setEntityLombokModel(true);  //是否开启Lombok
        strategy.setRestControllerStyle(true);  //设置Controller使用restful风格
        strategy.setLogicDeleteFieldName("is_delete");  //设置逻辑删除的字段
        //设置填充配置
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategy.setTableFillList(tableFills);
        //乐观锁
        strategy.setVersionFieldName("version");   
        mpg.setStrategy(strategy);

        //*********************************自定义配置Mapper.xml生成路径*********************************
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return projectPath + "/src/main/resources/mapper/"
                          + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
               //application文件中加:mybatis-plus.mapper-locations=classpath:mapper/*.xml
            }
        });
        cfg.setFileOutConfigList(focList);
        //选择 freemarker 引擎需要指定如下,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        //*********************************生成代码*********************************
        mpg.execute();
    }
}

3. 生成代码

你可能感兴趣的:(springboot,mybatis-plus)