SpringBoot整合MyBatis-Plus

使用过MyBatis的同学应该都有过这种体会当类里面要添加或删减字段的时候,就要去修改Mapper.xml修改相对应的SQL语句,这样相对来说就有点麻烦容易出错。今天给大家介绍一个工资MyBatis-Plus,plus是加强的意思,那MyBatis-Plus就是MyBatis的加强版,MyBatis—plus就解决了刚刚上面所说的问题,当然他还有很多优点,今天就来学习一下SpringBoot如何整合MyBatis-Plus吧。

MyBatis-Plus的优点

  1.无侵入,强大的CRUD功能;
  2.支持lambda形式调用;
  3.支持多种形式的自动生成主键;
  4.内置代码生成器,内置分页插件;
  5.内置全局拦截插件,内置sql注入剥离器;

对于 mybatis-plus 的使用,可以参照官网http://mp.baomidou.com/

一、创建数据库表

CREATE TABLE `tb_student` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `num` bigint(20) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `native_place` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

**二、创建SpringBoot项目

创建一个springboot项目 boketest

1、pom.xml文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zyyqc</groupId>
    <artifactId>boketest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>boketest</name>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- mybatis plus 代码生成器依赖 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- 代码生成器模板 -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.编写码生成器

CodeGenerator.Class

package com.zyyqc.boketest.generator;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

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

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取项目当前所在文件夹位置
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("zhangxiansho");
        gc.setOpen(false);
        // service 命名方式
        gc.setServiceName("%sService");
        // service impl 命名方式
        gc.setServiceImplName("%sServiceImpl");
        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setFileOverride(true);
        gc.setActiveRecord(true);
        // XML 二级缓存
        gc.setEnableCache(false);
        // XML ResultMap
        gc.setBaseResultMap(true);
        // XML columList
        gc.setBaseColumnList(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/boke?useUnicode=true&useSSL=false&characterEncoding=utf-8");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.zyyqc.boketest");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("cn.com.bluemoon.demo.entity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父类
        //strategy.setSuperControllerClass("cn.com.bluemoon.demo.controller");
        // 写于父类中的公共字段
        //strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        //去掉数据库表名的前缀,这里我的数据库中的表名加了“tb_”前缀
        strategy.setTablePrefix("tb_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

代码生成器中的一些基本配置比如作者名称,包的路径,数据库链接地址根据自己的实际情况进行调整。

3.执行代码生成器

执行代码生成器中的main方法,在控制台中输入要生成的表的表名,如下图


image.png

执行后可以清楚的看到自动创建了controller,entity,service,mapper等新包,并且生成了对应的java代码。


image.png

通过图片可以清楚的看出生成了tb_student和tb_excel_zip两张表对应的java类。

4.application.yml

spring:
  #数据库配置
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/boke?useUnicode=true&useSSL=false&characterEncoding=utf-8
    username: root
    password: root
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver

5.简单的CRUD

刚刚已经自动生成了大部分的java代码了,这样大大提高了我们的开发效率,不仅如此MyBatis-Plus还封装了大量的方法,下面就来试一下。

@RestController
@RequestMapping("/student")
public class StudentController {

    @Resource
    private StudentService studentService;

    @PostMapping("/saveOrUpdate")
    public String saveOrUpdate(@RequestBody Student student) {
        boolean saveOrUpdate = true;

        if (Objects.isNull(student.getId())) {
            saveOrUpdate = studentService.save(student);
        } else {
            saveOrUpdate = studentService.updateById(student);
        }

        if (saveOrUpdate) {
            return "保存成功!";
        } else {
            return "保存失败!";
        }
    }


    @PostMapping("/delete")
    public String delete(Long id) {
        boolean b = studentService.removeById(id);
        if (b) {
            return "删除成功";
        } else {
            return "删除失败";
        }
    }

    @PostMapping("/list")
    public List<Student> list() {
        List<Student> list = studentService.list();
        return list;
    }
}

上面所调用的save,updateById,removeById,list都是mybatis-plus封装好的使用很方便的,还有很多方法大家可以自己去研究一下。

6.分页查询

mybatis-plus内置了分页插件用起来也是很方便的首先需要添加一个配置类

@Configuration
public class MybatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }
}
 @PostMapping("/listBody")
    public List<Student> list(@RequestBody StudentQuery query) {
        Page<Student> page = studentService.queryPageList(query);
        return page.getRecords();
    }
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class StudentQuery implements Serializable{

    private static final long Serializable = 1L;
    private int currentPage = 1;

    private int pageSize = 10;
}

StudentQuery 类是分页查询的条件,里面包含了要查询的当前页currentPage和每一页的数据量pageSize,默认值是取第1页每一页10条数据。

接下来是service和mapper中的代码

@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    @Resource
    private StudentMapper studentMapper;
    
    @Override
    public Page<Student> queryPageList(StudentQuery query) {
        Page<Student> page = new Page<>(query.getCurrentPage(), query.getPageSize());
        LambdaQueryWrapper<Student> queryWrapper = new LambdaQueryWrapper<>();
        List<Student> students =  studentMapper.queryPageList(page,queryWrapper);
        page.setRecords(students);
        return page;
    }
/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author zhangxiansho
 * @since 2020-04-01
 */
public interface StudentMapper extends BaseMapper<Student> {

    List<Student> queryPageList(Page<Student> page, @Param("queryWrapper") Wrapper<Student> queryWrapper);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zyyqc.boketest.mapper.StudentMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zyyqc.boketest.entity.Student">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="num" property="num" />
        <result column="sex" property="sex" />
        <result column="age" property="age" />
        <result column="native_place" property="nativePlace" />
    </resultMap>
    <select id="queryPageList" resultType="com.zyyqc.boketest.entity.Student">
        select * from tb_student
        <where>
            ${queryWrapper.sqlSegment}
        </where>
</mapper>

接下来做个单元测试看一下结果

@Test
    void queryPageList() {
        Page<Student> page = studentService.queryPageList(new StudentQuery());
        if (CollectionUtils.isNotEmpty(page.getRecords())) {
            page.getRecords().forEach(System.out::println);
        }
    }

![image.png]
image.png

由图可知已经查出了第一页的10条数据。
好了到现在MyBatis-Plus的基本增删改查,分页操作就完成了,MyBatis-plus的更多使用就待你自己慢慢深入发掘了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。