• Mybatis-Plus-【通俗易懂全讲解】


    Mybatis-Plus

    简介

    MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
    详情见官网:https://baomidou.com/pages/24112f/#%E7%89%B9%E6%80%A7

    快速入门

    1. 建表

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

      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’);

    2. 创建一个空的Spring Boot工程

    3. 添加依赖MySQL,lombok,mybatis_plus

      mysql mysql-connector-java 8.0.28 org.projectlombok lombok 1.18.22 com.baomidou mybatis-plus-boot-starter 3.5.1
    4. 编写配置文件,连接数据库

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

    5. 传统方式pojo-dao(连接mybatis,配置mapper.xml文件)-service-controller
    5. 使用了mybatis-plus之后(继承BaseMapper接口,省略了mapper.xml文件

    • pojo

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

    • mapper接口

      //在对应的mapper上面继承基本接口就可以 BaseMapper
      @Repository//代表持久层
      public interface UserMapper extends BaseMapper {
      //所有的CRUD操作都已经编写完成了
      //你不需要像以前一样配置一大堆文件了
      }

    • 注意点,我们需要在主启动类上去扫描我们mapper包下的所有接口@MapperScan("com.kuang.mapper")

      //扫描我们的mapper文件夹
      @MapperScan(“com.kuang.mapper”)
      @SpringBootApplication
      public class MybatisPlusApplication {

      public static void main(String[] args) {
          SpringApplication.run(MybatisPlusApplication.class, args);
      }
      
      • 1
      • 2
      • 3

      }

    • 测试类中测试

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

      @Test
      void contextLoads() {
          //这里的参数是一个Wrapper,条件构造器,这里我们先不用,将其设为null
          //查询全部用户
          List userList = userMapper.selectList(null);
          userList.forEach(System.out::println);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      }

    思考问题

    1. SQL谁帮我们写的MyBatis-Plus
    2. 方法哪里来的?MyBatis-Plus

    配置日志

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

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

    在这里插入图片描述

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

    CRUD扩展

    插入操作

    insert插入

        @Test//测试插入
        public void textInsert() {
            User user = new User();
            user.setName("lala啦");
            user.setAge(3);
            user.setEmail("465386@qq.com");
            int result = userMapper.insert(user);//帮我们自动生成id
            System.out.println(result);//受影响的行数
            System.out.println(user);//发现,id会自动回填
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

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

    主键生成策略

    默认ASSIGN_ID全局唯一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. 数据库字段一定要是自增的!
      在这里插入图片描述
    3. 再次测试插入即可,并且自增量为1!

    其余IdType的源码解释

    public enum IdType {
        AUTO(0),//数据库id自增
        NONE(1),//未设置主键
        INPUT(2),//手动输入,就需要自己配置id了
        ASSIGN_ID(3),//默认的全局唯一id 
        ASSIGN_UUID(4);//全局唯一id
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    更新操作

     @Test
        //测试更新
        public void testUpdate(){
            User user = new User();
            //通过条件自动拼接动态sql
            user.setId(6L);
            user.setName("lala嘿嘿");
            user.setAge(3);
            user.setEmail("111111@qq.com");
            //注意:userById 但是参数是一个对象
            int i = userMapper.updateById(user);
            System.out.println(i);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述
    所有的sql都是自动帮你动态配置的!

    自动填充

    创建时间、修改时间!这些个操作都是自动化完成的,我们不希望手动更新!
    阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!

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

    1. 在表中新增字段create_time,update_time
      在这里插入图片描述

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

      private Date createTime;
      private Date updateTime;

    3. 再次更新查看结果即可
      在这里插入图片描述
      出现问题:除了插入记录,其余创建时间和更新时间都为null
      解决问题:在建字段的时候,需要设置该字段不能为空
      在这里插入图片描述

    方式二:代码级别

    1. 删除数据库中create_time,update_time这两个字段的默认值、update_time更新操作
      在这里插入图片描述

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

      //字段添加填充内容
      //插入的时候填充字段
      @TableField(fill = FieldFill.INSERT)
      private Date createTime;
      //插入和更新的时候填充字段
      @TableField(fill = FieldFill.INSERT_UPDATE)
      private Date updateTime;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    3. 编写处理器来处理这个注解即可!

      @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);
          //MetaObject[反射对象类]是Mybatis的工具类,通过MetaObject获取和设置对象的属性值。
          this.setFieldValByName("updateTime",new Date(),metaObject);
      }
      
      //更新时的填充策略
      @Override
      public void updateFill(MetaObject metaObject) {
          log.info("start update fill.....");
          this.setFieldValByName("updateTime",new Date(),metaObject);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      }

    4. 测试插入

    5. 测试更新、观察时间即可

    • 小结:但是有一点,我发现其他记录没有默认的创建create_time,update_time这两个字段,只有进行了插入或更新的字段这两个字段才会填充

    乐观锁

    乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,就上锁,更新失败
    悲观锁:顾名思义十分悲观,它总是认为会出现问题,无论干什么都会去上锁!再去操作

    我们这里主要讲解 乐观锁机制!
    乐观锁实现方式

    • 取出记录时,获取当前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

    测试一下Mybatis- Plus的乐观锁插件

    1. 给数据库中增加version字段!
      在这里插入图片描述

    2. 我们实体类要加对应的字段

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

      //扫描我们的mapper文件夹
      @MapperScan(“com.kuang.mapper”)
      @EnableTransactionManagement//自动管理事务开启,默认也是开启的
      @Configuration//这是一个配置类
      public class MybatisPlusConfig {
      //注册乐观锁插件
      @Bean
      public MybatisPlusInterceptor mybatisPlusInterceptor() {
      MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
      interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
      return interceptor;
      }
      }

    4. 测试一下

      //测试乐观锁成功
      @Test
      public void testOptimisticLocker(){
          //1.查询
          User user = userMapper.selectById(1L);
          //2.修改,它很乐观它觉得这个用户没有问题,,进行修改
          user.setName("呀嘿");
          user.setEmail("5555555@qq.com");
          user.setAge(2);
          //3.执行更新操作
          userMapper.updateById(user);
      }
      
      //测试乐观锁失败
      @Test
      public void testOptimisticLocker2(){
      
          //线程一
          User user = userMapper.selectById(1L);
          user.setName("yiyi嘿11");
          user.setEmail("111111@qq.com");
      
          //模拟另外一个线程执行了插队操作
          User user2 = userMapper.selectById(1L);
          user2.setName("yi嘿哈22");
          user2.setEmail("222222@qq.com");
      
          userMapper.updateById(user2);
      	//自旋锁来多次尝试提交!
          userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值!
      }
      
      • 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

    自旋锁(拓展)

    “自旋”就是自己在这里不停地循环,直到目标达成。而不像普通的锁那样,如果获取不到锁就进入阻塞

    查询操作

        //测试批量查询!
        @Test
        public void testSelectByBatchId(){
            List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
            users.forEach(System.out::println);
        }
    
        //按条件查询之一使用 map 操作
        @Test
        public void testSelectByBatchIds() {
            HashMap map = new HashMap<>();
            //自定义要查询
            map.put("name","Jack");
            List users = userMapper.selectByMap(map);
            users.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    分页查询

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

    1. 原始的limit进行分页
    2. pageHelper第三方插件
    3. MP其实也内置了分页插件!

    如何使用!

    1. 配置拦截器组件即可

      @Bean
      public MybatisPlusInterceptor mybatisPlusInterceptor() {
          MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();    
          //分页插件
          interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
          //乐观锁插件
          interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
          return interceptor;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    2. 直接使用Page对象即可!

      //测试分页查询
      @Test
      public void testPage(){
          //参数一:当前页
          //参数二:页面大小
          //使用了分页插件后,所有的分页操作也变得简单了
          IPage page = new Page<>(2, 5);
          userMapper.selectPage(page,null);
          page.getRecords().forEach(System.out::println);
          System.out.println(page.getTotal());
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    删除操作

    基本的删除操作

    //测试删除
        //通过id
        @Test
        public void testDeleteById(){
            userMapper.deleteById(1518117539816615937L);
        }
    
        //通过id批量删除
        @Test
        public void testDeleteBatchIds(){
            userMapper.deleteBatchIds(Arrays.asList(1518117539816615938L,8L));
        }
    
        //通过map删除
        @Test
        public void testDeleteMap(){
            HashMap map = new HashMap<>();
            map.put("name","yi嘿哈22");
            userMapper.deleteByMap(map);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

    逻辑删除

    物理删除:从数据库中直接移除
    逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!delete = 0>>delete=1

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

    1. 在数据表中增加一个delete字段
      在这里插入图片描述

    2. 实体类中增加属性

      @TableLogic//逻辑删除
      private Integer deleted;
      
      • 1
      • 2
    3. 配置!
      例: application.yml

      mybatis-plus:
      global-config:
      db-config:
      logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不进行@TableLogic注解)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    4. 测试一下删除
      执行的是update操作不是delete操作
      在这里插入图片描述
      数据没有被删除,只是deleted字段值被标记为1
      在这里插入图片描述
      查询的时候会自动拼接deleted,加上deleted=0的条件
      在这里插入图片描述

    CRUD小结

    以上的所有CRUD操作极其拓展操作,我们都必须精通掌握!会大大提高你的工作和写项目的效率!
    注意:以上操作仅供参考,根据版本不同和更新较快,主要以Mybatis-Plus官网内容为主,其内容也较好阅读。

    性能分析插件

    作用:性能分析拦截器,用于输出每条SQL语句极其执行时间
    如果超过这个时间就停止运行
    由于MP此版本较新,官网已经没有了MP性能分析插件,所以此处用了第三方p6spy插件

    1.导入pom相关依赖
    
    
    	com.baomidou
    	mybatis-plus-boot-starter
    	3.5.1
    
    
    
    	p6spy
    	p6spy
    	3.8.1
    
    
    
    	com.baomidou
    	mybatis-plus-generator
    	3.5.1
    
     
    2.修改 application.yml
    ### 默认配置如下
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8&tinyInt1isBit=true
        username: root
        password: 123456
    ### 修改配置如下
    spring:
      datasource:
      driver-class-name: com.p6spy.engine.spy.P6SpyDriver
      url: jdbc:p6spy:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8&tinyInt1isBit=true
      
    3.在项目的resources下添加"spy.properties" p6spy的位置文件
    modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
    # 自定义日志打印
    logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
    #日志输出到控制台
    appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
    # 使用日志系统记录 sql
    #appender=com.p6spy.engine.spy.appender.Slf4JLogger
    # 设置 p6spy driver 代理
    deregisterdrivers=true
    # 取消JDBC URL前缀
    useprefix=true
    # 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
    excludecategories=info,debug,result,commit,resultset
    # 日期格式
    dateformat=yyyy-MM-dd HH:mm:ss
    # 实际驱动可多个
    #driverlist=org.h2.Driver
    # 是否开启慢SQL记录
    outagedetection=true
    # 慢SQL记录标准 2 秒
    outagedetectioninterval=2
     
    4.执行查询接口
    控制台会显示如下代码
     Consume Time:20 ms 2020-06-30 09:26:25
     Execute SQL:SELECT ID, NAME, AGE, SEX, date_format( INPUT_DATE, '%Y-%c-%d %h:%i:%s' ) inputDate FROM student where 1=1 LIMIT 10 
    
    • 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

    使用性能分析插件,可以帮助我们提高效率!

    条件构造器

    十分重要
    我们写一些复杂的sql就可以用它来代替
    1.测试一,记住查看输出的SQL进行分析

    @Test
    void contextLoads(){
        //查询name不为空,邮箱不为空的用户,年龄大于等于24
        QueryWrapper wrapper = new QueryWrapper<>();//和mapper很像,但是wrapper是一个对象,不用put,而是去用方法
        wrapper
                .isNotNull("name")
                .isNotNull("email")
                .ge("age",24);
        userMapper.selectList(wrapper).forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    2.测试二,记住查看输出的SQL进行分析

    @Test
    void contextLoads2(){
         //查询名字为Tom的
         QueryWrapper wrapper = new QueryWrapper<>();
         wrapper.eq("name","Tom");
         User user = userMapper.selectOne(wrapper);//查询一个数据,出现多个结果使用List或者Map
         System.out.println(user);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.测试三,记住查看输出的SQL进行分析

    @Test
    void contextLoads3(){
        //查询年龄在20-30之间的用户
        QueryWrapper wrapper = new QueryWrapper<>();
        wrapper.between("age",20,30);//区间,不包括20和30
        Long count = userMapper.selectCount(wrapper);//查询结果数量
        System.out.println(count);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.测试四,记住查看输出的SQL进行分析

    //模糊查询
    @Test
    void contextLoads4(){
        QueryWrapper wrapper = new QueryWrapper<>();
        //t在% 左和右
        wrapper
                .notLike("name","a")//名字中没有a和A
                .likeRight("email","t");//邮箱以字母t开头
        userMapper.selectMaps(wrapper).forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.测试五,记住查看输出的SQL进行分析

    @Test
    void contextLoads5(){
        QueryWrapper wrapper = new QueryWrapper<>();
        // 在子查询中查出来
        wrapper.inSql("name","select name from user where id < 5");
        List objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    6.测试六

    @Test
    void contextLoads6(){
        QueryWrapper wrapper = new QueryWrapper<>();
        //通过id进行降序排序 ASC升序
        wrapper.orderByDesc("id");
        List users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码自动生成器

    dao、pojo、service、controller都自动编写完成!
    1.先写依赖

    
    
        org.freemarker
        freemarker
        2.3.31
    
    
    
        com.baomidou
        mybatis-plus-generator
        3.5.1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.运行代码

    package com.kuang;
    
    import com.baomidou.mybatisplus.generator.FastAutoGenerator;
    import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
    import com.baomidou.mybatisplus.generator.config.OutputFile;
    import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
    import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
    import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
    
    import java.util.Collections;
    
    public class lqc {
        public static void main(String[] args) {
            String projectPath = System.getProperty("user.dir");//user.dir	用户当前工作目录
            FastAutoGenerator.create("jdbc:p6spy:mysql://localhost:3306/mybatis_plus?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8", "root", "123456")
                    //1.全局配置
                    .globalConfig(builder -> {
                        builder.author("lqc") // 设置作者
                                .enableSwagger() // 开启 swagger 模式
                                .fileOverride() // 覆盖已生成文件
                                .outputDir(projectPath+"/src/main/java");// 指定输出目录
    
                    })
                    //3.包的配置
                    .packageConfig(builder -> {
                        builder.parent("com.kuang") // 设置父包名
                                .moduleName("blog") // 设置父包模块名
                                .pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath+"/src/main/java")); // 设置mapperXml生成路径
                    })
                    //4.策略配置
                    .strategyConfig(builder -> {
                        builder.addInclude("student") // 设置需要生成的表名
                                .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                    .execute();
            //2.数据库的配置
            new DataSourceConfig.
                    Builder("jdbc:p6spy:mysql://localhost:3306/mybatis_plus?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8","root","123456")
                    .dbQuery(new MySqlQuery())
                    .schema("mybatis_plus")
                    .typeConvert(new MySqlTypeConvert())
                    .keyWordsHandler(new MySqlKeyWordsHandler())
                    .build();
        }
    }
    
    • 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

    3.文件自动生成
    在这里插入图片描述
    爽歪歪

    –大部分内容来自狂神说JAVA

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    数据库索引的基本操作(sql语句)
    SSM+甘肃旅游系统 毕业设计-附源码211707
    js中各种数据类型检测与判定
    反射第一部分,获取Class对象,获取Constructor对象
    vscode launch.json
    .cn是几级域名?
    【arm实验2】按键中断事件控制实验
    Python和Java二选一该学啥?
    【Git】:远程仓库操作
    Vite4TSX前端版本号生成
  • 原文地址:https://blog.csdn.net/jiong9412/article/details/126112841