• SpringBoot教程(十三) SpringBoot集成MybatisPlus


    一、MybatisPlus简介

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

    Mybatis-Plus是一个国产框架,有中文的文档,所以使用起来还是很方便的,没有那么大的障碍。

    文档地址:baomidou.com/

    当前的最新版本是3.5.1

    文档上说的十分清楚,这里我就不多说了。直接进入集成步骤。

    二、集成步骤

    我们首先拉取一个feature/mybatisPlus的分支,在这个分支上演示springBoot集成MybatisPlus的用法。

    1. 引入 依赖

    
    
    
        4.0.0
    
        com.lsqingfeng.springboot
        springboot-learning
        1.0.0
    
        
            8
            8
        
    
        
            
                
                    org.springframework.boot
                    spring-boot-dependencies
                    2.6.2
                    pom
                    import
                
            
        
    
        
            
                org.springframework.boot
                spring-boot-starter-web
            
    
            
            
                org.projectlombok
                lombok
                1.18.22
                provided
            
    
            
            
                com.baomidou
                mybatis-plus-boot-starter
                3.5.1
            
    
            
                com.baomidou
                mybatis-plus-generator
                3.5.1
            
    
            
                org.freemarker
                freemarker
                2.3.31
            
    
            
            
                org.springframework.boot
                spring-boot-devtools
                true
            
    
            
            
                mysql
                mysql-connector-java
                runtime
            
        
    
    复制代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    其中mybatis-plus-boot-starter是核心的应用包

    mybatis-plus-generator和 freemarker是用来逆向生成的,通过逆向生成的工具类,可以帮助我们生成相应的实体,mapper, service,controller。基本可以实现近乎0代码开发单表的增删改查。

    2. 逆向生成

    我们接下来就先演示一下mybatis-plus的逆向生成功能。所谓逆向工程,是根据数据库的表结构来帮助我们生成代码,所以我们要先保证数据库中的表是已经建立完毕的。

    所谓逆向工程,其实就是一个工具类。我们把这个类直接放到我们的工程下,然后配置相关的数据库连接和生成的目录位置,和要生成的表即可,执行完毕后,就可以直接生成我们所需要的类。

    新版本的MybatisPlus自动生成的方式和旧版本的不太一样,大家使用的时候要注意,这一点在官方文档上已经做了具体说明。

    baomidou.com/pages/779a6…

    这里由于我们使用的是最新的版本,所以采用新版本的生成方式。

    我们在项目下创建一个utils的包,然后加入我们的工具类 MybatisPlusGenerator,具体内容如下。

    package com.lsqingfeng.springboot.utils;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.generator.FastAutoGenerator;
    import com.baomidou.mybatisplus.generator.config.*;
    import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    import com.baomidou.mybatisplus.generator.fill.Column;
    
    import java.util.Collections;
    
    /**
     * @className: MybatisPlusGenerator
     * @description:
     * @author: sh.Liu
     * @date: 2022-01-26 11:19
     */
    public class MybatisPlusGenerator {
        public static void main(String[] args) {
            FastAutoGenerator.create("jdbc:mysql://localhost:3306/springboot_learning?useUnicode=true&useSSL=false&characterEncoding=utf8", "root", "root")
                    .globalConfig(builder -> {
                        builder.author("springBoot-Learning") // 设置作者
                                //.enableSwagger() // 开启 swagger 模式
                                .fileOverride() // 覆盖已生成文件
                                .outputDir(System.getProperty("user.dir")+"/src/main/java"); // 指定输出目录
                    })
                    .packageConfig(builder -> {
                        builder.parent("com.lsqingfeng") // 设置父包名
                                .moduleName("springboot") // 设置父包模块名
                                // .service()  // 设置自定义service路径,不设置就是默认路径
                                .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") +"/src/main/resources/mapper/")); // 设置mapperXml生成路径
                    })
                    .strategyConfig(builder -> {
                        builder.addInclude("t_user") // 设置需要生成的表名
                                .addTablePrefix("t_", "c_")
                                // 设置自动填充的时间字段
                                .entityBuilder().addTableFills(
                                        new Column("create_time", FieldFill.INSERT),new Column("update_time", FieldFill.INSERT_UPDATE))
                        ; // 设置过滤表前缀
    
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                    .execute();
        }
    }
    复制代码
    
    • 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

    在这个类中,我们需要设置数据库的连接信息:包括数据库链接地址,用户名密码等。需要设置作者,是否开启swagger模式和生成代码的位置。这里使用系统变量user.dir就会直接获取到我们当前项目的路径。

    同时需要设置相应的报名,模块名和忽略的表名前缀。 addInclude方法里可以多个表名,用于设置为哪些表自动生成,也可以不设置,不设置的话默认会给当前库中的所有表生成相应代码。

    通过上面的代码运行后自动生成的controller, service, mapper默认位于 com.lsqingfeng.springboot下的controller, service, mapper表下。 mapper对应的xml文件位于 resources/mapper文件夹下。这些内容也都是可以进行修改的。

    生成好的文件默认情况如下;

    3. 添加配置

    逆向生成完毕,我们mybatis-Plus的基础环境就基本搭建完毕了。接下来就是做一下配置。

    首先我们需要在启动类上添加一个Mapper扫描的注解MapperScan,用来配置需要扫描的mapper包所在的位置。当然这个配置也可以放到任意的一个配置类上,效果是一样的。

    package com.lsqingfeng.springboot;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    /**
     * @className: SpringBootLearningApplication
     * @description: springboot启动类
     * @author: sh.Liu
     * @date: 2022-01-10 14:36
     */
    @SpringBootApplication
    @MapperScan("com.lsqingfeng.springboot.mapper")
    public class SpringBootLearningApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringBootLearningApplication.class, args);
        }
    }
    复制代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果我们想要使用Mybatis-Plus中的分页功能,我们还需要添加一个配置类,加入分页拦截器的配置。

    package com.lsqingfeng.springboot.config;
    
    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @className: MybatisPlusConfig
     * @description:
     * @author: sh.Liu
     * @date: 2022-03-04 14:55
     */
    @Configuration
    public class MybatisPlusConfig {
        /**
         * 老版本,目前已失效
         * @return
         */
        /**@Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            return paginationInterceptor;
        }*/
    
    
        /**
         * 新的分页插件,一缓和二缓遵循mybatis的规则,
         */
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }
    复制代码
    
    • 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

    再添加一个自动填充create_time和update_time的配置类:

    package com.lsqingfeng.springboot.config;
    
    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.reflection.MetaObject;
    import org.springframework.stereotype.Component;
    
    import java.time.LocalDateTime;
    
    /**
     * @className: MyMetaObjectHandler
     * @description:
     * @author: sh.Liu
     * @date: 2022-03-04 14:57
     */
    @Slf4j
    @Component
    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);
        }
    }
    复制代码
    
    • 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

    这个配置类是要和实体类上的注解配置使用的。由于已经在自动生成的工具类上做了设置,所以自动生成的实体中,createTime和updateTime上都会有对应注解,这样才能自动填充。

    /**
     * 创建时间
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    复制代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4. 测试

    写一个Controller测试一下:这里大家要注意一下mybatisPlus提供的一些常用api, page,list,getOne,save,update等。大家可以关注一下具体写法。

    package com.lsqingfeng.springboot.controller;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.metadata.IPage;
    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    import com.lsqingfeng.springboot.base.Result;
    import com.lsqingfeng.springboot.entity.User;
    import com.lsqingfeng.springboot.service.IUserService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    /**
     * 

    * 前端控制器 *

    * * @author springBoot-Learning * @since 2022-02-28 */ @RestController @RequestMapping("/user") public class UserController { /** * 构造方法注入 */ private final IUserService userService; public UserController(IUserService userService) { this.userService = userService; } @GetMapping("/save") public Result save(){ User user =new User(); user.setAge(18); user.setAddress("北京王府井大街"); user.setName("张某某"); userService.save(user); return Result.success(); } @GetMapping("/update") public Result update(Integer id){ User user =new User(); user.setId(id); user.setName("修改的名字"); userService.updateById(user); return Result.success(); } @GetMapping("/list") public Result list(){ // 返回所有 List list = userService.list(); return Result.success(list); } @GetMapping("/listByContion") public Result listByContion(){ /** * 条件查询, 通过QueryWrapper来实现查询的条件: * eq: 代表相等 * like: 模糊匹配 * orderBy: 排序 * in, notin * 大于,小于,between等 */ List list = userService.list(new LambdaQueryWrapper() // 查询年龄=11的 .eq(User::getAge, 11) // 模糊匹配 .like(User::getName, "%张%") // 排序,按照创建时间 .orderByDesc(User::getCreateTime) ); return Result.success(list); } @GetMapping("/getById") public Result getById(Integer id){ User user = userService.getById(id); return Result.success(user); } @GetMapping("/delete") public Result delete(Integer id){ userService.removeById(id); return Result.success(); } @GetMapping("/page") public Result page(int pageNum, int pageSize, String name){ IPage page = new Page<>(pageNum, pageSize); IPage page1 = userService.page(page, new LambdaQueryWrapper() // 主要演示这里可以加条件。在name不为空的时候执行 .eq(StringUtils.isNotEmpty(name), User::getName, "%" + name + "%")); return Result.success(page1); } } 复制代码
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    验证:

    save接口:

    数据库:

    更新接口:

    数据库:

    查询所有接口:

    条件查询接口:

    条件写死了,查询年龄=11, 名字包含张的,没有符合条件的数据:

    List list = userService.list(new LambdaQueryWrapper()
                    // 查询年龄=11的
                    .eq(User::getAge, 11)
                    // 模糊匹配
                    .like(User::getName, "%张%")
                    // 排序,按照创建时间
                    .orderByDesc(User::getCreateTime)
            );
    复制代码
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    根据id查询接口:

    分页查询:

    三、总结

    mybtisPlus的常用操作我们就已经介绍完了。mybatisPlus当前的使用热度也是越来越大,通过这篇文章相信大家应该会对mybatisPlus的使用有一个比较深刻的理解。

    使用的主要步骤就是,先设计库表,然后通过自动生成工具,生成我们所需要的实体、mapper、service等,Controller一般都是我们自己开发,无需使用他们生成的Controller,之后就可以在我们的项目中,通过调用相应的service, mapper来实现常用的增删改查操作。mybatisPlus火热的主要原因即使他们封装好的单表操作api,免去了我们书写大量sql的工作量,可以直接通过调用相应api的方式完成大部分的单表操作功能,非常的简便。

    初次之外,mybatisPlus提供了非常详细而又可读的中文文档,我们完全可以在文档中找到我们所有想要找到的内容。这一点应该也是国内很青睐他的一个重要原因吧。

    如果我们我们想要开发自定义的sql,使用方式和mybatis完全一样,因为它和完全兼容mybatis的,我们只需要在的mapper.xml文件中写自己的自定义sql就行了。

    另: 配套项目代码已托管中gitCode: gitcode.net/lsqingfeng/…

    所有文章也会在微信公众号首发更新,欢迎关注:

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

  • 相关阅读:
    day-3-2-3
    Win 11 打开未知文件/打开方式 该文件没有与之关联的应用来执行该操作。请安装应用,若已经安装应用,请在“默认应用设置”页面中创建关联。
    Linux之yum安装MySQL
    python subprocess 起来的进程怎么查看是否正在运行
    6-Dubbo架构设计与底层原理-服务导出源码分析(下)
    JDK1.8新特性---Optional
    【POJ No. 3368】 最频繁值 Frequent values
    「C#」异步编程玩法笔记-任务调度TaskScheduler
    react实战系列 —— 起步(mockjs、第一个模块、docusaurus)
    SpringBoot教程四定时任务cron表达式Shedule
  • 原文地址:https://blog.csdn.net/m0_67402013/article/details/126114741