一、MybatisPlus简介
MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
Mybatis-Plus是一个国产框架,有中文的文档,所以使用起来还是很方便的,没有那么大的障碍。
文档地址:baomidou.com/
当前的最新版本是3.5.1
文档上说的十分清楚,这里我就不多说了。直接进入集成步骤。
二、集成步骤
我们首先拉取一个feature/mybatisPlus的分支,在这个分支上演示springBoot集成MybatisPlus的用法。
1. 引入 依赖
代码语言:javascript复制<?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,具体内容如下。
代码语言:javascript复制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文件夹下。这些内容也都是可以进行修改的。
生成好的文件默认情况如下;
3. 添加配置
逆向生成完毕,我们mybatis-Plus的基础环境就基本搭建完毕了。接下来就是做一下配置。
首先我们需要在启动类上添加一个Mapper扫描的注解MapperScan,用来配置需要扫描的mapper包所在的位置。当然这个配置也可以放到任意的一个配置类上,效果是一样的。
代码语言:javascript复制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中的分页功能,我们还需要添加一个配置类,加入分页拦截器的配置。
代码语言:javascript复制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的配置类:
代码语言:javascript复制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上都会有对应注解,这样才能自动填充。
代码语言:javascript复制/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
复制代码
4. 测试
写一个Controller测试一下:这里大家要注意一下mybatisPlus提供的一些常用api, page,list,getOne,save,update等。大家可以关注一下具体写法。
代码语言:javascript复制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接口:
数据库:
更新接口:
数据库:
查询所有接口:
条件查询接口:
条件写死了,查询年龄=11, 名字包含张的,没有符合条件的数据:
代码语言:javascript复制List<User> list = userService.list(new LambdaQueryWrapper<User>()
// 查询年龄=11的
.eq(User::getAge, 11)
// 模糊匹配
.like(User::getName, "%张%")
// 排序,按照创建时间
.orderByDesc(User::getCreateTime)
);
复制代码
根据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/…