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

·  阅读 1125

一、MybatisPlus简介

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

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

文档地址:baomidou.com/

当前的最新版本是3.5.1

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

二、集成步骤

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

1. 引入 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lsqingfeng.springboot</groupId>
    <artifactId>springboot-learning</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.6.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

        <!-- lombok 代码简化 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

        <!-- mybatis-plus 所需依赖  -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>

        <!-- 开发热启动 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- MySQL连接 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>
复制代码

其中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();
    }
}
复制代码

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

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

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

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

image.png

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);
    }
}
复制代码

如果我们想要使用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;
    }
}
复制代码

再添加一个自动填充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);
    }
}
复制代码

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

/**
 * 创建时间
 */
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

/**
 * 更新时间
 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
复制代码

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;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @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<User> list = userService.list();
        return Result.success(list);
    }

    @GetMapping("/listByContion")
    public Result listByContion(){
        /**
         * 条件查询, 通过QueryWrapper来实现查询的条件:
         * eq: 代表相等
         * like: 模糊匹配
         * orderBy: 排序
         * in, notin
         * 大于,小于,between等
         */
        List<User> list = userService.list(new LambdaQueryWrapper<User>()
                // 查询年龄=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<User> page = new Page<>(pageNum, pageSize);

        IPage<User> page1 = userService.page(page, new LambdaQueryWrapper<User>()
                // 主要演示这里可以加条件。在name不为空的时候执行
                .eq(StringUtils.isNotEmpty(name), User::getName, "%" + name + "%"));

        return Result.success(page1);
    }
}
复制代码

验证:

save接口:

image.png 数据库:

image.png

更新接口:

image.png

数据库:

image.png

查询所有接口:

image.png

条件查询接口:

image.png

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

List<User> list = userService.list(new LambdaQueryWrapper<User>()
                // 查询年龄=11的
                .eq(User::getAge, 11)
                // 模糊匹配
                .like(User::getName, "%张%")
                // 排序,按照创建时间
                .orderByDesc(User::getCreateTime)
        );
复制代码

根据id查询接口:

image.png

分页查询: image.png

三、总结

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

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

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

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

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

所有文章也会在微信公众号首发更新,欢迎关注: 一缕82年的清风

分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改