MyBatisPlus 官方 + 狂神

MyBatisPlus概述

需要的基础:MyBatis、Spring、SpringMVC

为什么学习它呢?MyBatisPlus可以节省我们大量工作时间,所有的CRUD代码他都可以自动化完成!

JPA、tk-mapper、MyBatisPlus

偷懒的!

简介

是什么?MyBatis本来就是简化JDBC操作的!

官网:简介 | MyBatis-Plus (baomidou.com),简化Mybaits!
MyBatisPlus 官方 + 狂神
MyBatisPlus 官方 + 狂神

特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库

任何能使用 mybatis 进行 crud, 并且支持标准 sql 的数据库

框架结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lMZkyekV-1625980277476)(MyBatisPlus笔记 狂神说java.assets/mybatis-plus-framework.jpg)]

代码托管

Gitee (opens new window)| Github

快速开始

使用第三方组件:

1、导入对应的依赖

2、研究依赖如何配置

3、代码如何编写

4、提高扩展技术能力!

步骤:

  1. 创建数据库 mybatis_plus

  2. 创建user表

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)
);
--真实开发中,version(乐观锁)、delete(逻辑删除)、gmt_create、gmt_modified

其对应的数据库 Data 脚本如下:

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');
  1. 初始化工程

创建一个空的 Spring Boot 工程

可以使用 Spring Initializer (opens new window)快速初始化一个 Spring Boot 工程

  1. 添加依赖
    MyBatisPlus 官方 + 狂神
    <!-- 数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.3</version>
    </dependency>

说明:我们使用 mybatis-plus 可以节省我们大量的代码,尽量不要同时导入 mybatis 和 mybatis-plus!版本的差异!

  1. 配置数据库

application.yml 配置文件中添加 MySQL 数据库的相关配置:

# mysql 5 驱动不同 com.mysql.jdbc.Driver
# mysql 8 驱动不同com.mysql.cj.jdbc.Driver、需要增加时区的配置serverTimezone=GMT%2B8

# DataSource Config
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹:

@SpringBootApplication
@MapperScan("com.mingm.mapper")
public class Application {

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

}
  1. 编码

编写实体类 User.java(此处使用了 Lombok (opens new window)简化代码)

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

编写Mapper类 UserMapper.java

//在对应的mapper上面继承基本的接口BaseMapper
@ResponseBody //代表持久层
public interface UserMapper extends BaseMapper<User> {
    //所有的CRUD操作都已经内置编写完成了
    //你不需要像以前的配置一大堆文件了
}
  1. 开始使用

添加测试类,进行功能测试:

@SpringBootTest
public class SampleTest {

    // 继承了BaseMapper,所有的方法都来自己父类
    // 我们也可以编写自己的扩展方法!
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        // 参数是一个 Wrapper ,条件构造器,这里我们先不用,用null
        // 查询全部用户
        List<User> userList = userMapper.selectList(null);
        Assert.assertEquals(5, userList.size());
        userList.forEach(System.out::println);
    }

}

UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件

控制台输出:

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)

TIP

完整的代码示例请移步:Spring Boot 快速启动示例 (opens new window)| Spring MVC 快速启动示例(opens new window)

思考问题?

1、SQL谁帮我们写的 ? MyBatis-Plus 都写好了 !

2、方法哪里来的? MyBatis-Plus 都写好了!

配置日志

我们所有的sql现在是不可见的,我们希望知道它是怎么执行的,所以我们必须要看日志.

mybatis-plus:  configuration:    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

MyBatisPlus 官方 + 狂神

配置完毕日志之后,后面的学习就需要注意这个自动生成的SQL,你们就会喜欢上 MyBatis-Plus!

CRUD&扩展

插入操作

Insert 插入

@Testpublic void testInsert() {    User user = new User();    user.setName("Dainel");    user.setAge(3);    user.setEmail("daniel@alibaba.com");    int result = userMapper.insert(user);// 帮我们自动生成id    System.out.println(result);// 受影响的行数    System.out.println(user);// 发现: id自动回填}

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

主键生成策略

默认 ID_WORKER 全局唯一id

分布式系统唯一id生成:https://www.cnblogs.com/haoxinyue/p/5208136.html

雪花算法:

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

主键自增

我们需要配置主键自增:

  1. 实体类字段上 @TableId(type = IdType.AUTO)
  2. 数据库字段上一定是自增的

MyBatisPlus 官方 + 狂神

  1. 再次测试即可

其余的IdType源码解释

public enum IdType {    AUTO(0), // 数据库id自增    NONE(1), // 未设置主键    INPUT(2), // 手动输入,自己写id    ID_WORKER(3), // 默认的全局唯一id    UUID(4), // 全局唯一id uuid    ID_WORKER_STR(5); // ID_WORKER 字符串表示法}

更新操作

//测试更新@Testpublic void testUpdate(){    User user = new User();    // 通过条件自动拼接动态sql    user.setId(6L);    user.setName("关注我的微信公众号");    user.setAge(18);    // 注意: updateById 但是参数是一个 对象    int i = userMapper.updateById(user);    System.out.println(i);}

MyBatisPlus 官方 + 狂神

所有的sql都是自动帮你动态配置的!

自动填充

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

**阿里巴巴开发手册:**所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!

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

  1. 在表中新增字段 create_time,update_time
    MyBatisPlus 官方 + 狂神

  2. 再次测试插入方法,我们需要先把实体类同步!

private LocalDateTime createTime;private LocalDateTime updateTime;

再次更新查看结果即可。

方式二:代码级别

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

MyBatisPlus 官方 + 狂神

  1. 实体类的字段属性上需要增加注解
public class User {       ....            // 注意!这里需要标记为填充字段    @TableField(fill = FieldFill.INSERT)    private Date createTime;    @TableField(fill = FieldFill.INSERT_UPDATE)    private Date updateTime;}
  1. 编写处理器来处理这个注解即可! 自定义实现类 MyMetaObjectHandler
@Slf4j@Component // 一定不要忘记把处理器加到IOC容器中public class MyMetaObjectHandler implements MetaObjectHandler {    // 插入时候的填充策略    @Override    public void insertFill(MetaObject metaObject) {        log.info("start insert fill ....");        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)        // 或者//        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)        // 或者//        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)    }    // 更新时的填充策略    @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)    }}
  1. 测试插入

  2. 测试更新,观察时间

源码 FieldFill

public enum FieldFill {    /**     * 默认不处理     */    DEFAULT,    /**     * 插入填充字段     */    INSERT,    /**     * 更新填充字段     */    UPDATE,    /**     * 插入和更新填充字段     */    INSERT_UPDATE}

注意事项:

  • 填充原理是直接给entity的属性设置值!!!
  • 注解则是指定该属性在对应情况下必有值,如果无值则入库会是null
  • MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充
  • 字段必须声明TableField注解,属性fill选择对应策略,该声明告知Mybatis-Plus需要预留注入SQL字段
  • 填充处理器MyMetaObjectHandler在 Spring Boot 中需要声明@Component@Bean注入
  • 要想根据注解FieldFill.xxx字段名以及字段类型来区分必须使用父类的strictInsertFill或者strictUpdateFill方法
  • 不需要根据任何来区分可以使用父类的fillStrategy方法

乐观锁

在面试过程中,我们经常会被问到乐观锁,悲观锁。

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

悲观锁:顾名思义,它总是认为总是出现问题,无论干什么都上锁!再去操作!

乐观锁 OptimisticLockerInnerInterceptor 实现方式:

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

步骤:

  1. 数据库中增加一个version字段

MyBatisPlus 官方 + 狂神

  1. 在实体类的字段上加上@Version注解
@Version // 乐观锁的version注解private Integer version;

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!
  1. 注册组件 编写Config文件!
// Spring Boot 方式@Configuration@MapperScan("按需修改")public class MybatisPlusConfig {    /**     * 旧版     */    @Bean    public OptimisticLockerInterceptor optimisticLockerInterceptor() {        return new OptimisticLockerInterceptor();    }        /**     * 新版     */    @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor() {        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁插件        return mybatisPlusInterceptor;    }}
  1. 测试一下,查看测试结果即可。
    // 测试乐观锁成功    @Test    public void testVersionSuccess(){        // 1. 查询用户信息        User user = userMapper.selectById(1L);        // 2. 修改用户信息        user.setName("fan");        user.setAge(24);        // 3. 执行更新操作        userMapper.updateById(user);    }    // 测试乐观锁更新失败!多线程下    @Test    public void testVersionFall(){        // 线程1        User user1 = userMapper.selectById(1L);        user1.setName("fan111");        user1.setAge(14);        // 线程2 模拟另外一个线程执行了插队操作        User user2 = userMapper.selectById(1L);        user2.setName("fan222");        user2.setAge(24);        userMapper.updateById(user2);                //自旋锁来多次尝试提交!        userMapper.updateById(user1); //如果没有乐观锁就会覆盖插队线程的值    }}

分页查询

分页在网站使用的十分之多!

  1. 原始使用limit进行分页

  2. pageHelper第三方插件

  3. MybatisPlus内置了分页插件

如何使用?

  1. 在配置文件中 添加分页插件
    // 最新版    @Bean    public MybatisPlusInterceptor mybatisPlusInterceptor() {        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁插件        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页插件        return interceptor;    }
  1. UserMapper.xml 等同于编写一个普通 list 查询,mybatis-plus 自动替你分页
<mapper namespace="com.mingm.mapper.UserMapper">    <select id="selectPageVo" resultType="com.mingm.pojo.User">        SELECT * FROM user WHERE age=#{age}    </select></mapper>
  1. 直接使用Page对象即可,调用分页!
    @Test    public void testPage(){        // 参数一:当前页        // 参数二:页面大小        // 使用了分页插件之后,所有的分页操作也变得简单的!        Page<User> page = new Page<>(2,5);        userMapper.selectPage(page,null);        page.getRecords().forEach(System.out::println);        System.out.println(page.getTotal());    }    @Test    public void selectUserPage() {        // 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分        // page.setOptimizeCountSql(false);        // 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询        // 要点!! 分页返回的对象与传入的对象是同一个        Page<User> userPage = new Page<>(1,2);        userMapper.selectPageVo(userPage,11);//此处 11为xml中自定义的参数!        userPage.getRecords().forEach(System.out::println);        System.out.println(userPage.getTotal());    }

删除操作

// 测试删除@Testpublic void testdelete(){    userMapper.deleteById(6L);}// 测试批量删除@Testpublic void testdeleteBatchId(){    userMapper.deleteBatchIds(Arrays.asList(1287326823914405893L,1287326823914405894L));}//通过map删除@Testpublic void testDeleteByMap(){    HashMap<String, Object> map = new HashMap<>();    map.put("name","mingm");    userMapper.deleteByMap(map);}

我们在工作中会遇到一些问题:逻辑删除!

逻辑删除

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

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

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

字段类型支持说明:

  • 支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
  • 如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()

附录:

  • 逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
  • 如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。

测试:

  1. 在数据库表中增加一个deleted字段
    MyBatisPlus 官方 + 狂神

  2. 实体类字段上加上@TableLogic注解

@TableLogic // 逻辑删除private Integer deleted;
  1. 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig
  • application.yml
mybatis-plus:  configuration:    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  mapper-locations: mybatis-plus/*.xml  global-config:    db-config:#      logic-delete-field: deleted  # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)      logic-delete-value: 1 # 逻辑已删除值(默认为 1)      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. 测试即可!

MyBatisPlus 官方 + 狂神

记录依旧在数据库,但是值已经变化了!

MyBatisPlus 官方 + 狂神

条件构造器

十分重要:wrapper

我们写一些复杂的sql就可以使用它来代替!

MyBatisPlus 官方 + 狂神

测试!

package com.mingm.springbootmybatisplus;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mingm.mapper.UserMapper;
import com.mingm.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@SpringBootTest
public class WrapperTests {
    @Autowired
    private UserMapper userMapper;

    @Test
    void test1(){
        //查询name不为空的用户  并且邮箱不为空的用户  年龄大于等于12
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("name")
                .isNotNull("email")  //email字段不为空
                .ge("age",12);  //大于等于 >=
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

    @Test
    void test2(){
        //查询名字Jack
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "Jack");
        //SELECT id,name,age,email,version,create_time,update_time,deleted FROM user WHERE deleted=0 AND (name = ?)
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }
    @Test
    void test3(){
        //查询年龄在19到21岁之间的用户数量  包含!
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age", 20, 21); //区间
        //SELECT COUNT( * ) FROM user WHERE deleted=0 AND (age BETWEEN ? AND ?)
//        Integer count = userMapper.selectCount(wrapper);
        ArrayList<User> userList = (ArrayList<User>) userMapper.selectList(wrapper);
        //SELECT id,name,age,email,version,create_time,update_time,deleted FROM user WHERE deleted=0 AND (age BETWEEN ? AND ?)
        userList.forEach(System.out::println);
        System.out.println(userList.size());
    }

    //模糊查询
    @Test
    void test4(){
        //查询年龄在19到30岁之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //左和右
        wrapper.notLike("name", "A")
                .likeRight("email", "t");
//        Preparing: SELECT id,name,age,email,version,create_time,update_time,deleted FROM user
//        //         WHERE deleted=0 AND (name NOT LIKE ? AND email LIKE ?)
//        ==> Parameters: %b%(String), t%(String)
        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }

    @Test
    void test5(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //id 在子查询中查出来
        wrapper.inSql("id", "select id from user where id < 3");
        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

    @Test
    void test6(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //通过id进行排序
        wrapper.orderByDesc("id");
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

    @Test
    void test7(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //id 在子查询中查出来
        wrapper.inSql("id", "select id from user where id < 5");
        //SELECT id,name,age,email,version,create_time,update_time,deleted FROM user
        // //     WHERE deleted=0 AND (id IN (select id from user where id < 5))
        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }
    @Test
    void test8(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //通过id进行排序
        wrapper.orderByDesc("id");
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

}

其余的测试,可以自己下去多练习!

代码自动生成器

代码生成器 | MyBatis-Plus (baomidou.com)

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

  • 演示效果图:

MyBatisPlus 官方 + 狂神

  • 狂神 版配置
public class Code {
    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("ChanV");
        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.setUrl("jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        //3、包的配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("blog");
        pc.setParent("com.chanv");
        pc.setEntity("pojo");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        //4、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("user");    //设置要映射的表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);    //自动lombok
        strategy.setLogicDeleteFieldName("deleted");
        //自动填充配置
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategy.setTableFillList(tableFills);
        //乐观锁
        strategy.setVersionFieldName("version");
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true);     //localhost:8080/hello_id_2
        mpg.setStrategy(strategy);

        mpg.execute();  //执行代码构造器
    }
}
上一篇:移动端滚动方案:better-scroll


下一篇:CSS之transform介绍与动态LOGO的制作