Mybatis-Plus详解,只用看这一篇就够了

MyBatis-Plus(3.5.1)详解

简介

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

img

特性

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

支持数据库

  • MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
  • 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

快速开始(这里是一股脑把所有的代码写入,有注解,可以先理解,快速开始后面会有讲解)

全部项目(包含sql文件)gitee:https://gitee.com/i-dont-recognize-you/mybatis-plus
如果不知道git怎么操作的可以看看 (git是工作必备的知识,所以我就不把项目放在百度云盘了,如果急需,请在评论区留言点赞,我会私信你)Git使用详解全图文(基于gitee),看这一篇就够了_我认不到你的博客-CSDN博客_gitee

先引入MySQL表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `age` int(11) NULL DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `version` int(10) NULL DEFAULT 1 COMMENT '乐观锁',
  `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
  `deleted` int(1) NULL DEFAULT 0 COMMENT '逻辑删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1511997312817717256 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '赵2222', 18, '156451612@168.com', 4, NULL, '2022-04-08 20:02:42', 1);
INSERT INTO `user` VALUES (2, '????', 20, 'test2@baomidou.com', 1, NULL, NULL, 0);
INSERT INTO `user` VALUES (3, 'Tom', 28, 'test3@baomidou.com', 1, NULL, NULL, 0);
INSERT INTO `user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com', 1, NULL, NULL, 0);
INSERT INTO `user` VALUES (5, 'Billie', 24, 'test5@baomidou.com', 1, NULL, NULL, 0);

SET FOREIGN_KEY_CHECKS = 1;

结构如下

建包

在这里插入图片描述

导入springboot依赖

这是mybatis-plus集成springboot需要所有的maven依赖

<dependencies>
        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--mubatis-plus-->
        <!--mubatis-plus是自己开发的,并非官方的-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--mybatis-plus-generator 生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>

        <!-- 模板引擎 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        <!-- freemarker,作为代码生成器mapper文件的模板引擎使用(当然也可以使用velocity,二选一即可) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
		
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

配置

application.yaml文件配置

这是mybatis-plus全部需要的yaml配置,逻辑删除部分是之后会用到的

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

#    配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  # 配置逻辑删除 
  global-config:
    db-config:
      logic-delete-value: 1  # 1 为逻辑删除后的字段
      logic-not-delete-value: 0  # 0 为没有逻辑删除的字段
      logic-delete-field: deleted  #对应实体类的字段 写了这个在实体类中就不需要写注解了
Springboot启动类中加入@MapperScan注解

或者在mapper包中的类下加入@Mapper注解效果是一样的,但挨个写太麻烦,集中写在springboot启动器类上就行

@MapperScan("com.zhao.mapper")//扫描我们的mapper包
@SpringBootApplication
public class MybatisPlusStudyApplication {

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

}

在这里插入图片描述

编码

编写实体类(pojo)中User.java

这里也是把所有用到的代码一起展示了(使用了lombok插件自动生成了get/set等方法)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    // 对应数据库中的主键 (uuid、自增id、雪花算法、redis、zookeeper)
//    AUTO 是自增策略,在数据库中药开启自增
//    NONE 是未设置主键
//    INPUT 手动输入
//    ASSIGN_ID 全局唯一id 雪花算法
//    ASSIGN_UUID 全局唯一id uuid
    @TableId(type = IdType.ASSIGN_ID) //这是默认的创造id的方法:雪花算法
    private Long id;

    @TableField(value = "`name`") //如果取的名字和关键字一样导致sql报错,加上次注解
    private String name;

    private Integer age;
    private String email;

    //字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

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

//    @TableLogic //逻辑删除注解 在yaml中配置了就不用写注解了
    private Integer deleted;
}
在实体类配置了乐观锁注解需要加入一个类来统一管理这些注解MyBatisPlusConfig.java名字随便取
@MapperScan("com.zhao.mapper")//扫描我们的mapper文件夹 这里添加了@MapperScan注解就不需要Springboot启动类上加入@MapperScan注解了
@EnableTransactionManagement //事务控制
@Configuration //配置类
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注册乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
在实体类配置了创建时间、修改时间注解需要在一个类中统一管理
@Slf4j  //日志  这里是lombok的日志注解(加不加无所谓)
@Component //一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill.....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
在实体类中添加了逻辑删除注解只需要在application.yaml中添加一下代码(在上面的yaml文件中已经配置了)
mybatis-plus:
  # 配置逻辑删除
  global-config:
    db-config:
      logic-delete-value: 1  # 1 为逻辑删除后的字段
      logic-not-delete-value: 0  # 0 为没有逻辑删除的字段
      logic-delete-field: deleted  #对应实体类的字段 写了这个在实体类中就不需要写注解了
编写Mapper包下面的UserMapper接口
//在对应的Mapper上面实现基本的接口 BaseMapper
@Repository // 代表持久层
//@Mapper
public interface UserMapper extends BaseMapper<User> {
    //所有的CRUD操作都已经编写完成了
    //你不需要像以前的配置一大堆文件了
}

在测试类中使用

这里是基础的测试方法,没用用到wrapper构造器,也是一股脑的全部代码,后面会解释

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

    @Test
    void contextLoads() {
        //这里的参数是一个 Wrapper , 条件构造器,这里我们先不用
        //查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
    //测试插入
    @Test
    void contextLoads2() {
        User user = new User();
        user.setName("赵平安");
        user.setAge(5);
        user.setEmail("2030502369@qq.com");
        int insert = userMapper.insert(user);
        System.out.println(insert);
        System.out.println(user);
    }
    //测试更新
    @Test
    void contextLoads3() {
        User user = new User();
        user.setId(1512011571182272513L);
        user.setName("66666666");
        // 注意虽然名字是updateById 但参数是一个对象
        int i = userMapper.updateById(user);
        System.out.println(i);
    }
    //测试乐观锁成功
    @Test
    void testOptimisticLocker() {
        //1.查询用户信息
        User user = userMapper.selectById(1L);
        //2.修改用户信息
        user.setName("赵");
        user.setEmail("156451612@168.com");
        //3.执行更新操作
        userMapper.updateById(user);
    }

    //测试乐观锁失败  多线程下
    @Test
    void testOptimisticLocker2() {
        //线程1
        User user = userMapper.selectById(1L);
        user.setName("赵111");
        user.setEmail("156451612@168.com");
        //模拟另外一个线程执行了插队操作
        User user2 = userMapper.selectById(1L);
        user2.setName("赵2222");
        user2.setEmail("156451612@168.com");
        userMapper.updateById(user2);
        userMapper.updateById(user);
    }
    //测试查询
    //批量查询
    @Test
    public void testSelectById(){
        List<User> user = userMapper.selectBatchIds(Arrays.asList(1,2,3));
        user.forEach(System.out::println);
    }
    //条件查询 map
    @Test
    public void testSelectByBathchIds(){
        HashMap<String, Object> map = new HashMap<>();
        //自定义查询
        map.put("name","Tom");
        map.put("age",28);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }
    //测试分页查询
    @Test
    public void testPage(){
        // 参数一: 当前页
        // 参数二: 页面大小
        Page<User> page = new Page<>(1,5);
        userMapper.selectPage(page,null);
        page.getRecords().forEach(System.out::println);
        System.out.println(page.getTotal()); //总共多少条记录
    }
    //测试删除
    @Test
    public void testDeleteById(){
        userMapper.deleteById(1L);
    }
    //通过id批量删除
    @Test
    public void testDeleteBatchById(){
        userMapper.deleteBatchIds(Arrays.asList(1512010867575152642L,1512009402454482945L));
    }
    //通过map删除
    @Test
    public void testDeleteMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","赵平安");
        userMapper.deleteByMap(map);
    }
}

这里使用了wrapper构造器来写sql代码

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

    @Test
    void contextLoads() {
        //查询 name不为空的用户,且邮箱不为空的用户,年龄大于等于12
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name")
                .isNotNull("email")
                        .ge("age",12);
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
    @Test
    void test2() {
        //查询 name等于赵平安
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name","赵平安");
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }
    @Test
    void test3() {
        //查询 年龄在20~30之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age",20,30);
        Long aLong = userMapper.selectCount(wrapper);//查询结果数
        System.out.println(aLong);
    }
    //模糊查询
    @Test
    void test4() {
        //查询 年龄在20~30之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.notLike("name","e")       //名字中不包含e的
                .likeRight("email","t");       //右边 t%
        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");    通过id升序排序   wrapper.orderByAsc("id");
        wrapper.orderByDesc("id");
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
}

这些就是MP的使用,到这为止除了代码生成器(逆向工程)没写(代码生成器代码实在是太多了,在最后会讲到)

详解(借鉴于狂神)

CRUD扩展(没使用Wrapper)

插入操作(实体类中id主键可以加注解,不加注解默认使用雪花算法,实体类中createTime创建时间、updateTime更新时间需要加入注解,并写一个类来统一管理)

实体类:
    // 对应数据库中的主键 (uuid、自增id、雪花算法、redis、zookeeper)
//    AUTO 是自增策略,在数据库中药开启自增
//    NONE 是未设置主键
//    INPUT 手动输入
//    ASSIGN_ID 全局唯一id 雪花算法
//    ASSIGN_UUID 全局唯一id uuid
    @TableId(type = IdType.ASSIGN_ID) //这是默认的创造id的方法:雪花算法
    private Long id;
    //字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
MyMetaObjectHandler类管理创建、更新时间注解(名字随便)
@Slf4j  //日志
@Component //一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill.....");
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }
}

注意:如果 更新时间 updateTime字段报错 Could not set property ‘updateTime‘,需要将Java中的字段类型改为java.time.LocalDateTime,赋值的话LocalDateTime.now()即可

@Slf4j  //日志
@Component //一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
        this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill.....");
        this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
    }
}

Insert插入 重点id自动赋值

// 测试插入
@Test
public void testInsert(){
User user = new User();
user.setName("狂神说Java");
user.setAge(3);
user.setEmail("24736743@qq.com");
int result = userMapper.insert(user); // 帮我们自动生成id
System.out.println(result); // 受影响的行数
System.out.println(user); // 发现,id会自动回填
}

看执行的sql代码给id自动赋值了一个Long长整形,使用了雪花算法(ASSIGN_ID)(这也是MP默认的id生成,可以在Use实体类中自行修改)

在这里插入图片描述

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

更新操作(实体类更新时间updateTime字段需要加入注解,并写一个类来管理(同上))

update更新 重点数据库更新时间自动更新

//测试更新
    @Test
    void contextLoads3() {
        User user = new User();
        user.setId(1512011571182272513L);
        user.setName("66666666");
        // 注意虽然名字是updateById 但参数是一个对象
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

这里自动更新了时间 并寻找数据表中没有被逻辑删除的数据(逻辑删除后面讲)

在这里插入图片描述

乐观锁(实体类Version字段需要加入注解,并写一个类来管理)

实体类:
    //乐观锁  Version 注解
    @Version
    private Integer version;
MyBatisPlusConfig类管理乐观锁注解
@MapperScan("com.zhao.mapper")//扫描我们的mapper文件夹 这里加了不用在springboot启动类中在加入此注解
@EnableTransactionManagement //事务控制
@Configuration //配置类
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注册乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页插件
//        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

select搜索后(MP自动)执行update更新

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

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

乐观锁实现方式:

  • 取出记录时,获取当前 version

  • 更新时,带上这个version 执行

  • 更新时, set version = newVersion where version = oldVersion

  • 如果version不对,就更新失败

乐观锁说白了就是怕多线程时导致数据库更新错误

乐观锁:1、先查询,获得版本号 version = 1
-- A
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1
成功案例
// 测试乐观锁成功!
@Test
public void testOptimisticLocker(){
// 1、查询用户信息
User user = userMapper.selectById(1L);
// 2、修改用户信息
user.setName("kuangshen");
user.setEmail("24736743@qq.com");
// 3、执行更新操作
userMapper.updateById(user);
}
失败案例
// 测试乐观锁失败!多线程下
@Test
public void testOptimisticLocker2(){
// 线程 1
User user = userMapper.selectById(1L);
user.setName("kuangshen111");
user.setEmail("24736743@qq.com");
// 模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName("kuangshen222");
user2.setEmail("24736743@qq.com");
userMapper.updateById(user2);
// 自旋锁来多次尝试提交!
userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
}

在这里插入图片描述

查询操作

select查询

// 测试查询
@Test
public void testSelectById(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
// 测试批量查询!
@Test
public void testSelectByBatchId(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
users.forEach(System.out::println);
}
// 按条件查询之一使用map操作
@Test
public void testSelectByBatchIds(){
HashMap<String, Object> map = new HashMap<>();
// 自定义要查询
map.put("name","狂神说Java");
map.put("age",3);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}

分页查询

分页查询的几种方法

  • 原生limit分页
  • pageHelper第三方插件
  • MP内置的分页插件
使用

1.配置分页插件

@MapperScan("com.zhao.mapper")//扫描我们的mapper文件夹 这里加了不用在springboot启动类中在加入此注解
@EnableTransactionManagement //事务控制
@Configuration //配置类
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //注册乐观锁插件
//        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

2.直接使用Page对象即可

    //测试分页查询
    @Test
    public void testPage(){
        // 参数一: 当前页(1)
        // 参数二: 页面大小(5)
        Page<User> page = new Page<>(1,5);
        userMapper.selectPage(page,null);
        page.getRecords().forEach(System.out::println);
        System.out.println(page.getTotal()); //总共多少条记录
    }

删除操作(只需配置application.yaml文件)

delect删除

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

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

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

逻辑删除只需要在application.yaml中配置就行
#    配置日志
mybatis-plus:
  # 配置逻辑删除
  global-config:
    db-config:
      logic-delete-value: 1  # 1 为逻辑删除后的字段
      logic-not-delete-value: 0  # 0 为没有逻辑删除的字段
      logic-delete-field: deleted  #对应实体类的字段 写了这个在实体类中就不需要写注解了
在实体类中使用注解(因为在yaml中配置了deleted为逻辑删除字段就不需要在实体类加注解了)
//    @TableLogic //逻辑删除注解 在yaml中配置了就不用写注解了
    private Integer deleted;
测试删除
    //测试删除
    @Test
    public void testDeleteById(){
        userMapper.deleteById(1L);
    }
    //通过id批量删除
    @Test
    public void testDeleteBatchById(){
        userMapper.deleteBatchIds(Arrays.asList(1512010867575152642L,1512009402454482945L));
    }
    //通过map删除
    @Test
    public void testDeleteMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","赵平安");
        userMapper.deleteByMap(map);
    }

可以看见删除还是使用的update更新操作,把deleted字段变为了1,查询时会在where中添加deleted=0,这样我们就查询不到deleted=1的字段了,这样就完成了逻辑删除

在这里插入图片描述

性能分析器

在 MP 3.2.0 版本后移除了性能分析器

推荐使用p6spy第三方插件 可以在https://blog.csdn.net/li521wang/article/details/104002897学习

条件构造器(终于到心心念念的Wrapper环节了)

先看看官方有多少方法(这里还没截完)、我讲些常用的

在这里插入图片描述

测试一:记住查看输出的SQL进行分析
@Test
void contextLoads() {
// 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("name")
.isNotNull("email")
.ge("age",12);
userMapper.selectList(wrapper).forEach(System.out::println); // 和我们刚才学习的map对比一下
}
测试二:记住查看输出的SQL进行分析
    @Test
    void test2() {
        //查询 name等于赵平安
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name","赵平安");
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }
测试三:记住查看输出的SQL进行分析
@Test
void test3(){
// 查询年龄在 20 ~ 30 岁之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30); // 区间
Integer count = userMapper.selectCount(wrapper);// 查询结果数
System.out.println(count);
}
测试四:记住查看输出的SQL进行分析
//模糊查询
    @Test
    void test4() {
        //查询 年龄在20~30之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.notLike("name","e")       //名字中不包含e的(%e%)
                .likeRight("email","t");       //右边 t%
        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }
测试五:记住查看输出的SQL进行分析
    @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);
    }
测试六:记住查看输出的SQL进行分析
    @Test
    void test6() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //通过id降序排序   wrapper.orderByDesc("id");    通过id升序排序   wrapper.orderByAsc("id");
        wrapper.orderByDesc("id");
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

其他的测试,自己多去练习:https://baomidou.com/pages/10c804/#abstractwrapper

代码自动生成器(逆向工程)

需要的maven依赖(在之前的快速开始中已经引入了)

        <!--mubatis-plus-->
        <!--mubatis-plus是自己开发的,并非官方的-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--mybatis-plus-generator 生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- freemarker,作为代码生成器mapper文件的模板引擎使用(当然也可以使用velocity,二选一即可) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

引入jar包后就可以使用了写一个测试类然后导入代码使用

package com.zhao;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;


import java.util.*;

/**
 * <p>
 * 代码生成器(快速版本)
 * </p>
 *
 * @author 赵平安
 * @since 2022-4-12 0022 16:51
 */
public class FastCodeGenerator {

    // 基础信息配置
    // 数据库连接字符
    private static final String URL = "jdbc:mysql://localhost:3306/shoppingmall?useUnicode=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf8";
    // 数据库用户名
    private static final String USERNAME = "root";
    // 数据库密码
    private static final String PASSWORD = "123456";
    // 项目根路径。生成结果如:D:\MyProject\spring-boot
    private static final String projectRootPath = System.getProperty("user.dir");
    // 项目根路径(测试用,非通用)(此句是本项目测试用的。实际项目中,包括多模块项目,请注释掉此句,使用上句)
//    private static final String projectRootPath = System.getProperty("user.dir") + "/study-mybatis-plus-fast-generator";
    // 父包名。用于生成的java文件的import。
//    private static final String parentPackageName = "com.cxhit.mybatisplus.generator";
    private static final String parentPackageName = "com.zhao.projectname";

    /**
     * 执行此处
     */
    public static void main(String[] args) {
        // 简单示例,适用于单模块项目
        simpleGenerator();
        // 完整示例,适用于多模块项目
//        completeGenerator();
    }

    /**
     * 【单模块】简单的实现方案
     */
    protected static void simpleGenerator() {

        // 包路径
        String packagePath = projectRootPath + "/src/main/java";
        // XML文件的路径
        String mapperXmlPath = projectRootPath + "/src/main/resources/Mybatis/mapper";

        // 开始执行代码生成
        FastAutoGenerator.create(URL, USERNAME, PASSWORD)
                // 1. 全局配置
                .globalConfig(builder -> builder
                        // 作者名称
                        .author("赵平安")
                        // 开启覆盖已生成的文件。注释掉则关闭覆盖。
                        // .fileOverride()
                        // 禁止打开输出目录。注释掉则生成完毕后,自动打开生成的文件目录。
                        .disableOpenDir()
                        // 指定输出目录。如果指定,Windows生成至D盘根目录下,Linux or MAC 生成至 /tmp 目录下。
                        .outputDir(packagePath)
                        // 开启swagger2.注释掉则默认关闭。
                        // .enableSwagger()
                        // 指定时间策略。
                        .dateType(DateType.TIME_PACK)
                        // 注释时间策略。
                        .commentDate("yyyy-MM-dd")
                )

                // 2. 包配置
                .packageConfig((scanner, builder) -> builder
                        // 设置父表名
                        .parent(parentPackageName)
//                        .moduleName(scanner.apply("请输入模块名:"))
                        // mapper.xml 文件的路径。单模块下,其他文件路径默认即可。
                        .pathInfo(Collections.singletonMap(OutputFile.xml, mapperXmlPath))
                        //改实体类名字为pojo
                                .entity("pojo")
                )

                // 3. 策略配置
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?生成所有表,请输入[all]:")))
                        // 阶段1:Entity实体类策略配置
                        .entityBuilder()
                        // 开启生成实体时生成字段注解。
                        // 会在实体类的属性前,添加[@TableField("nickname")]
                        .enableTableFieldAnnotation()
                        // 逻辑删除字段名(数据库)。
                        .logicDeleteColumnName("deleted")
                        // 逻辑删除属性名(实体)。
                        // 会在实体类的该字段属性前加注解[@TableLogic]
                        .logicDeletePropertyName("deleted")
                        // 会在实体类的该字段上追加注解[@TableField(value = "create_time", fill = FieldFill.INSERT)]
                        .addTableFills(new Column("create_time", FieldFill.INSERT))
                        // 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
                        .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
                        // 阶段2:Mapper策略配置
                        .mapperBuilder()
                        // 开启 @Mapper 注解。
                        // 会在mapper接口上添加注解[@Mapper]
                        .enableMapperAnnotation()
                        // 启用 BaseResultMap 生成。
                        // 会在mapper.xml文件生成[通用查询映射结果]配置。
                        .enableBaseResultMap()
                        // 启用 BaseColumnList。
                        // 会在mapper.xml文件生成[通用查询结果列 ]配置
                        .enableBaseColumnList()
                        // 阶段4:Controller策略配置
                        .controllerBuilder()
                        // 会在控制类中加[@RestController]注解。
                        .enableRestStyle()
                        // 开启驼峰转连字符
                        .enableHyphenStyle()
                        .build()
                )

                // 4. 模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                //.templateEngine(new BeetlTemplateEngine())
                .templateEngine(new FreemarkerTemplateEngine())

                // 5. 执行
                .execute();
    }

    /**
     * 【多模块使用】完整的实现方案
     */
    protected static void completeGenerator() {
        //【1】基础信息配置
        // 指定模块名,用于生成的java文件的import。
        String moduleName = scanner("请输入模块名:");
        // 六个文件的路径。多模块项目下,一般来说每个文件的路径都是不同的(根据项目实际,可能在不同的模块下)。
        String entityPath = projectRootPath + "/project-entity/src/main/java/com/yourdomain/projectname/entity/" + moduleName;
        String mapperPath = projectRootPath + "/project-dao/src/main/java/com/yourdomain/projectname/mapper/" + moduleName;
        String mapperXmlPath = projectRootPath + "/project-dao/src/main/resources/mapper/" + moduleName;
        String servicePath = projectRootPath + "/project-service/src/main/java/com/yourdomain/projectname/service/" + moduleName;
        String serviceImplPath = projectRootPath + "/project-service/src/main/java/com/yourdomain/projectname/service/" + moduleName + "/impl";
        String controllerPath = projectRootPath + "/project-controller/src/main/java/com/yourdomain/projectname/controller/" + moduleName;
        // 关于以上写法的解释:
        // --- 假设我们的项目有四个模块:project-entity、project-dao、project-service、project-controller
        // --- project-entity 的包路径:com.yourdomain.projectname.eneity,
        //   ---则生成system模块下的sys_user表,生成的实体文件将放在:com.yourdomain.projectname.entity.system包下,SysUser.java。
        // --- project-dao 的包路径:com.yourdomain.projectname.mapper,
        //   ---则生成system模块下的sys_user表,生成的mapper接口文件将放在:com.yourdomain.projectname.mapper.system包下,类名为:SysUserMapper.java。
        // --- 其他文件以此类推,即每个模块放MVC结构中对应的类型文件。
        // --- 注意:这里最后的文件路径修改了,下文配置中的【2 包配置】中的包路径也要同步修改!否则生成的java文件,首句import会报错。原因是路径错误。

        // 【2】开始执行代码生成
        FastAutoGenerator.create(URL, USERNAME, PASSWORD)
                // 1. 全局配置
                .globalConfig(builder -> builder
                        // 作者名称
                        .author("赵平安")
                        // 开启覆盖已生成的文件。注释掉则关闭覆盖。请谨慎开启此选项!
                        // .fileOverride()
                        // 禁止打开输出目录。注释掉则生成完毕后,自动打开生成的文件目录。
                        .disableOpenDir()
                        // 指定输出目录。多模块下,每个类型的文件输出目录不一致,在包配置阶段配置。
                        // .outputDir(packagePath)
                        // 开启swagger2。注释掉则默认关闭。
                        // .enableSwagger()
                        // 开启 kotlin 模式。注释掉则关闭此模式
                        // .enableKotlin()
                        // 指定时间策略。
                        .dateType(DateType.TIME_PACK)
                        // 注释时间策略。
                        .commentDate("yyyy-MM-dd")
                )

                // 2. 包配置
                .packageConfig((scanner, builder) -> builder
                        // 阶段1:各个文件的包名设置,用来拼接每个java文件的第一句:package com.XXX.XXX.XXX.xxx;
                        // 父包名配置
                        .parent(parentPackageName)
                        // 输入模块名。此模块名会在下面的几个包名前加。多模块项目,请根据实际选择是否添加。
                        // .moduleName(moduleName)
                        .entity("entity." + moduleName)
                        .mapper("mapper." + moduleName)
                        .service("service." + moduleName)
                        .serviceImpl("service." + moduleName + ".impl")
                        .controller("controller." + moduleName)
                        .other("other")
                        // 阶段2:所有文件的生成路径配置
                        .pathInfo(
                                new HashMap<OutputFile, String>() {{
                                    // 实体类的保存路径
                                    put(OutputFile.entity, entityPath);
                                    // mapper接口的保存路径
                                    put(OutputFile.mapper, mapperPath);
                                    // mapper.xml文件的保存路径
                                    put(OutputFile.xml, mapperXmlPath);
                                    // service层接口的保存路径
                                    put(OutputFile.service, servicePath);
                                    // service层接口实现类的保存路径
                                    put(OutputFile.serviceImpl, serviceImplPath);
                                    // 控制类的保存路径
                                    put(OutputFile.controller, controllerPath);
                                }}
                        )
                )

                // 3. 策略配置【请仔细阅读每一行,根据项目实际项目需求,修改、增删!!!】
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?生成所有表,请输入[all]:")))
                        // 阶段1:Entity实体类策略配置
                        .entityBuilder()
                        // 设置父类。会在生成的实体类名后:extends BaseEntity
                        // .superClass(BaseEntity.class)
                        // 禁用生成 serialVersionUID。(不推荐禁用)
                        // .disableSerialVersionUID()
                        // 开启生成字段常量。
                        // 会在实体类末尾生成一系列 [public static final String NICKNAME = "nickname";] 的语句。(一般在写wapper时,会用到)
                        // .enableColumnConstant()
                        // 开启链式模型。
                        // 会在实体类前添加 [@Accessors(chain = true)] 注解。用法如 [User user=new User().setAge(31).setName("snzl");](这是Lombok的注解,需要添加Lombok依赖)
                        // .enableChainModel()
                        // 开启 lombok 模型。
                        // 会在实体类前添加 [@Getter] 和 [@Setter] 注解。(这是Lombok的注解,需要添加Lombok依赖)
                        // .enableLombok()
                        // 开启 Boolean 类型字段移除 is 前缀。
                        // .enableRemoveIsPrefix()
                        // 开启生成实体时生成字段注解。
                        // 会在实体类的属性前,添加[@TableField("nickname")]
                        .enableTableFieldAnnotation()
                        // 逻辑删除字段名(数据库)。
                        .logicDeleteColumnName("deleted")
                        // 逻辑删除属性名(实体)。
                        // 会在实体类的该字段属性前加注解[@TableLogic]
                        .logicDeletePropertyName("deleted")
                        // 数据库表映射到实体的命名策略(默认下划线转驼峰)。一般不用设置
                        // .naming(NamingStrategy.underline_to_camel)
                        // 数据库表字段映射到实体的命名策略(默认为 null,未指定按照 naming 执行)。一般不用设置
                        // .columnNaming(NamingStrategy.underline_to_camel)
                        // 添加父类公共字段。
                        // 这些字段不会出现在新增的实体类中。
                        .addSuperEntityColumns("id", "delete_time")
                        // 添加忽略字段。
                        // 这些字段不会出现在新增的实体类中。
                        // .addIgnoreColumns("password")
                        // 添加表字段填充
                        // 会在实体类的该字段上追加注解[@TableField(value = "create_time", fill = FieldFill.INSERT)]
                        .addTableFills(new Column("create_time", FieldFill.INSERT))
                        // 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
                        .addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
                        // 全局主键类型。如果MySQL主键设置为自增,则不需要设置此项。
                        // .idType(IdType.AUTO)
                        // 格式化文件名称。
                        // 如果不设置,如表[sys_user]的实体类名是[SysUser]。设置成下面这样,将是[SysUserEntity]
                        // .formatFileName("%sEntity")

                        // 阶段2:Mapper策略配置
                        .mapperBuilder()
                        // 设置父类
                        // 会在mapper接口方法集成[extends BaseMapper<XXXEntity>]
                        // .superClass(BaseMapper.class)
                        // 开启 @Mapper 注解。
                        // 会在mapper接口上添加注解[@Mapper]
                        .enableMapperAnnotation()
                        // 启用 BaseResultMap 生成。
                        // 会在mapper.xml文件生成[通用查询映射结果]配置。
                        .enableBaseResultMap()
                        // 启用 BaseColumnList。
                        // 会在mapper.xml文件生成[通用查询结果列 ]配置
                        .enableBaseColumnList()
                        // 设置缓存实现类
                        // .cache(MyMapperCache.class)
                        // 格式化 mapper 文件名称。
                        // 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper]。写成下面这种形式后,将变成[SysUserDao]。
                        // .formatMapperFileName("%sDao")
                        // 格式化 xml 实现类文件名称。
                        // 如果不设置,如表[sys_user],默认的文件名是[SysUserMapper.xml],写成下面这种形式后,将变成[SysUserXml.xml]。
                        // .formatXmlFileName("%sXml")

                        // 阶段3:Service策略配置
                        // .serviceBuilder()
                        // 设置 service 接口父类
                        // .superServiceClass(BaseService.class)
                        // 设置 service 实现类父类
                        // .superServiceImplClass(BaseServiceImpl.class)
                        // 格式化 service 接口文件名称
                        // 如果不设置,如表[sys_user],默认的是[ISysUserService]。写成下面这种形式后,将变成[SysUserService]。
                        // .formatServiceFileName("%sService")
                        // 格式化 service 实现类文件名称
                        // 如果不设置,如表[sys_user],默认的是[SysUserServiceImpl]。
                        // .formatServiceImplFileName("%sServiceImpl")

                        // 阶段4:Controller策略配置
                        .controllerBuilder()
                        // 设置父类。
                        // 会集成此父类。
                        // .superClass(BaseController.class)
                        // 开启生成 @RestController 控制器
                        // 会在控制类中加[@RestController]注解。
                        .enableRestStyle()
                        // 开启驼峰转连字符
                        .enableHyphenStyle()

                        // 最后:构建
                        .build()
                )

                //模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                //.templateEngine(new BeetlTemplateEngine())
                .templateEngine(new FreemarkerTemplateEngine())

                // 执行
                .execute();
    }

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    private static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入").append(tip).append(":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }
}

创建完成

在这里插入图片描述

代码生成器不需要深入的解读,拿来用就行,但如果你需要配置自己需要的包名,类名等可以看看下面的讲解

代码生成器配置讲解

数据库配置(DataSourceConfig)
基础配置
属性说明示例
urljdbc路径jdbc:mysql://127.0.0.1:3306/mybatis-plus
username数据库账号root
password数据库密码123456
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .build();
可选配置
方法说明示例
dbQuery(IDbQuery)数据库查询new MySqlQuery()
schema(String)数据库 schema(部分数据库适用)mybatis-plus
typeConvert(ITypeConvert)数据库类型转换器new MySqlTypeConvert()
keyWordsHandler(IKeyWordsHandler)数据库关键字处理器new MySqlKeyWordsHandler()
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
    .dbQuery(new MySqlQuery())
    .schema("mybatis-plus")
    .typeConvert(new MySqlTypeConvert())
    .keyWordsHandler(new MySqlKeyWordsHandler())
    .build();
全局配置(GlobalConfig)
方法说明示例
fileOverride覆盖已生成文件默认值:false
disableOpenDir禁止打开输出目录默认值:true
outputDir(String)指定输出目录/opt/baomidou/ 默认值: windows:D:// linux or mac : /tmp
author(String)作者名baomidou 默认值:作者
enableKotlin开启 kotlin 模式默认值:false
enableSwagger开启 swagger 模式默认值:false
dateType(DateType)时间策略DateType.ONLY_DATE 默认值: DateType.TIME_PACK
commentDate(String)注释日期默认值: yyyy-MM-dd
new GlobalConfig.Builder()
    .fileOverride()
    .outputDir("/opt/baomidou")
    .author("baomidou")
    .enableKotlin()
    .enableSwagger()
    .dateType(DateType.TIME_PACK)
    .commentDate("yyyy-MM-dd")
    .build();
包配置(PackageConfig)
方法说明示例
parent(String)父包名默认值:com.baomidou
moduleName(String)父包模块名默认值:无
entity(String)Entity 包名默认值:entity
service(String)Service 包名默认值:service
serviceImpl(String)Service Impl 包名默认值:service.impl
mapper(String)Mapper 包名默认值:mapper
xml(String)Mapper XML 包名默认值:mapper.xml
controller(String)Controller 包名默认值:controller
other(String)自定义文件包名输出自定义文件时所用到的包名
pathInfo(Map<OutputFile, String>)路径配置信息Collections.singletonMap(OutputFile.mapperXml, “D://”)
new PackageConfig.Builder()
    .parent("com.baomidou.mybatisplus.samples.generator")
    .moduleName("sys")
    .entity("po")
    .service("service")
    .serviceImpl("service.impl")
    .mapper("mapper")
    .xml("mapper.xml")
    .controller("controller")
    .other("other")
    .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://"))
    .build();
模板配置(TemplateConfig)
方法说明示例
disable禁用所有模板
disable(TemplateType…)禁用模板TemplateType.ENTITY
entity(String)设置实体模板路径(JAVA)/templates/entity.java
entityKt(String)设置实体模板路径(kotlin)/templates/entity.java
service(String)设置 service 模板路径/templates/service.java
serviceImpl(String)设置 serviceImpl 模板路径/templates/serviceImpl.java
mapper(String)设置 mapper 模板路径/templates/mapper.java
mapperXml(String)设置 mapperXml 模板路径/templates/mapper.xml
controller(String)设置 controller 模板路径/templates/controller.java
new TemplateConfig.Builder()
    .disable(TemplateType.ENTITY)
    .entity("/templates/entity.java")
    .service("/templates/service.java")
    .serviceImpl("/templates/serviceImpl.java")
    .mapper("/templates/mapper.java")
    .mapperXml("/templates/mapper.xml")
    .controller("/templates/controller.java")
    .build();
注入配置(InjectionConfig)
方法说明示例
beforeOutputFile(BiConsumer<TableInfo, Map<String, Object>>)输出文件之前消费者
customMap(Map<String, Object>)自定义配置 Map 对象Collections.singletonMap(“test”, “baomidou”)
customFile(Map<String, String>)自定义配置模板文件Collections.singletonMap(“test.txt”, “/templates/test.vm”)
new InjectionConfig.Builder()
    .beforeOutputFile((tableInfo, objectMap) -> {
        System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
    })
    .customMap(Collections.singletonMap("test", "baomidou"))
    .customFile(Collections.singletonMap("test.txt", "/templates/test.vm"))
    .build();
策略配置(StrategyConfig)
方法说明示例
enableCapitalMode开启大写命名默认值:false
enableSkipView开启跳过视图默认值:false
disableSqlFilter禁用 sql 过滤默认值:true,语法不能支持使用 sql 过滤表的话,可以考虑关闭此开关
enableSchema启用 schema默认值:false,多 schema 场景的时候打开
ikeTable(LikeTable)模糊表匹配(sql 过滤)likeTable 与 notLikeTable 只能配置一项
notLikeTable(LikeTable)模糊表排除(sql 过滤)likeTable 与 notLikeTable 只能配置一项
addInclude(String…)增加表匹配(内存过滤)include 与 exclude 只能配置一项
addExclude(String…)增加表排除匹配(内存过滤)include 与 exclude 只能配置一项
addTablePrefix(String…)增加过滤表前缀
addTableSuffix(String…)增加过滤表后缀
addFieldPrefix(String…)增加过滤字段前缀
addFieldSuffix(String…)增加过滤字段后缀
entityBuilder实体策略配置
controllerBuildercontroller 策略配置
mapperBuildermapper 策略配置
serviceBuilderservice 策略配置
new StrategyConfig.Builder()
    .enableCapitalMode()
    .enableSkipView()
    .disableSqlFilter()
    .likeTable(new LikeTable("USER"))
    .addInclude("t_simple")
    .addTablePrefix("t_", "c_")
    .addFieldSuffix("_flag")
    .build();
Entity 策略配置(实体类)
方法说明示例
nameConvert(INameConvert)名称转换实现
superClass(Class<?>)设置父类BaseEntity.class
superClass(String)设置父类com.baomidou.global.BaseEntity
disableSerialVersionUID禁用生成 serialVersionUID默认值:true
enableColumnConstant开启生成字段常量默认值:false
enableChainModel开启链式模型默认值:false
enableLombok开启 lombok 模型默认值:false
enableRemoveIsPrefix开启 Boolean 类型字段移除 is 前缀默认值:false
enableTableFieldAnnotation开启生成实体时生成字段注解默认值:false
enableActiveRecord开启 ActiveRecord 模型默认值:false
versionColumnName(String)乐观锁字段名(数据库)
versionPropertyName(String)乐观锁属性名(实体)
logicDeleteColumnName(String)逻辑删除字段名(数据库)
logicDeletePropertyName(String)逻辑删除属性名(实体)
naming数据库表映射到实体的命名策略默认下划线转驼峰命名:NamingStrategy.underline_to_camel
columnNaming数据库表字段映射到实体的命名策略默认为 null,未指定按照 naming 执行
addSuperEntityColumns(String…)添加父类公共字段
addIgnoreColumns(String…)添加忽略字段
addTableFills(IFill…)添加表字段填充
addTableFills(List)添加表字段填充
idType(IdType)全局主键类型
convertFileName(ConverterFileName)转换文件名称
formatFileName(String)格式化文件名称
new StrategyConfig.Builder()
    .entityBuilder()
    .superClass(BaseEntity.class)
    .disableSerialVersionUID()
    .enableChainModel()
    .enableLombok()
    .enableRemoveIsPrefix()
    .enableTableFieldAnnotation()
    .enableActiveRecord()
    .versionColumnName("version")
    .versionPropertyName("version")
    .logicDeleteColumnName("deleted")
    .logicDeletePropertyName("deleteFlag")
    .naming(NamingStrategy.no_change)
    .columnNaming(NamingStrategy.underline_to_camel)
    .addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")
    .addIgnoreColumns("age")
    .addTableFills(new Column("create_time", FieldFill.INSERT))
    .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
    .idType(IdType.AUTO)
    .formatFileName("%sEntity")
    .build();
Controller 策略配置
方法说明示例
superClass(Class<?>)设置父类BaseController.class
superClass(String)设置父类com.baomidou.global.BaseController
enableHyphenStyle开启驼峰转连字符默认值:false
enableRestStyle开启生成@RestController 控制器默认值:false
convertFileName(ConverterFileName)转换文件名称
formatFileName(String)格式化文件名称
new StrategyConfig.Builder()
    .controllerBuilder()
    .superClass(BaseController.class)
    .enableHyphenStyle()
    .enableRestStyle()
    .formatFileName("%sAction")
    .build();
Service 策略配置
方法说明示例
superServiceClass(Class<?>)设置 service 接口父类BaseService.class
superServiceClass(String)设置 service 接口父类com.baomidou.global.BaseService
superServiceImplClass(Class<?>)设置 service 实现类父类BaseServiceImpl.class
superServiceImplClass(String)设置 service 实现类父类com.baomidou.global.BaseServiceImpl
convertServiceFileName(ConverterFileName)转换 service 接口文件名称
convertServiceImplFileName(ConverterFileName)转换 service 实现类文件名称
formatServiceFileName(String)格式化 service 接口文件名称
formatServiceImplFileName(String)格式化 service 实现类文件名称
new StrategyConfig.Builder()
    .serviceBuilder()
    .superServiceClass(BaseService.class)
    .superServiceImplClass(BaseServiceImpl.class)
    .formatServiceFileName("%sService")
    .formatServiceImplFileName("%sServiceImp")
    .build();
Mapper 策略配置
方法说明示例
superClass(Class<?>)设置父类BaseMapper.class
superClass(String)设置父类com.baomidou.global.BaseMapper
enableMapperAnnotation开启 @Mapper 注解默认值:false
enableBaseResultMap启用 BaseResultMap 生成默认值:false
enableBaseColumnList启用 BaseColumnList默认值:false
cache(Class<? extends Cache>)设置缓存实现类MyMapperCache.class
convertMapperFileName(ConverterFileName)转换 mapper 类文件名称
convertXmlFileName(ConverterFileName)转换 xml 文件名称
formatMapperFileName(String)格式化 mapper 文件名称
formatXmlFileName(String)格式化 xml 实现类文件名称
new StrategyConfig.Builder()
    .mapperBuilder()
    .superClass(BaseMapper.class)
    .enableMapperAnnotation()
    .enableBaseResultMap()
    .enableBaseColumnList()
    .cache(MyMapperCache.class)
    .formatMapperFileName("%sDao")
    .formatXmlFileName("%sXml")
    .build();
方法说明示例
superClass(Class<?>)设置父类BaseMapper.class
superClass(String)设置父类com.baomidou.global.BaseMapper
enableMapperAnnotation开启 @Mapper 注解默认值:false
enableBaseResultMap启用 BaseResultMap 生成默认值:false
enableBaseColumnList启用 BaseColumnList默认值:false
cache(Class<? extends Cache>)设置缓存实现类MyMapperCache.class
convertMapperFileName(ConverterFileName)转换 mapper 类文件名称
convertXmlFileName(ConverterFileName)转换 xml 文件名称
formatMapperFileName(String)格式化 mapper 文件名称
formatXmlFileName(String)格式化 xml 实现类文件名称
new StrategyConfig.Builder()
    .mapperBuilder()
    .superClass(BaseMapper.class)
    .enableMapperAnnotation()
    .enableBaseResultMap()
    .enableBaseColumnList()
    .cache(MyMapperCache.class)
    .formatMapperFileName("%sDao")
    .formatXmlFileName("%sXml")
    .build();

在这就讲完了,看到这了就点个赞吧,老铁

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我认不到你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值