1.前言
1.1 简介
MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
1.2 特点
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.3 官网
2.代码
2.1 引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
2.2 配置
# mybatis-plus配置
mybatis-plus:
# 启动检查MyBatis配置文件
check-config-location: false
# MyBatis配置文件位置
config-location:
# MyBaits别名包扫描路径
type-aliases-package: com.qiangesoft.mybatisplus.entity
# Mapper所对应的XML文件位置 默认【classpath*:/mapper/**/*.xml】
mapper-locations: classpath*:/mapper/*Mapper.xml
# TypeHandler扫描路径
type-handlers-package:
configuration:
# 日志打印
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 是否开启自动驼峰命名规则
map-underscore-to-camel-case: true
# 开启Mybatis二级缓存,默认为true
cache-enabled: true
global-config:
# 控制台mybatis-plus的logo
banner: true
db-config:
# 全局默认主键类型
id-type: auto
# 逻辑删除配置
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
2.3 代码生成
2.3.1 表准备
CREATE TABLE `sys_user` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`dept_id` bigint DEFAULT NULL COMMENT '部门id',
`user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '账号',
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '密码',
`nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '昵称',
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户邮箱',
`phone_number` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '手机号码',
`sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '0' COMMENT '用户性别(0男 1女)',
`avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '头像地址',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
`deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标志',
`version` int DEFAULT NULL COMMENT '乐观锁',
`create_by` bigint DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新人',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户信息';
2.3.2 引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
2.3.3 代码生成器
package com.qiangesoft.mybatisplus.config;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import java.util.Collections;
/**
* MybatisPlus代码生成器
*
* @author qiangesoft
* @date 2024-03-12
*/
public class MybatisPlusGenerator {
/**
* 主方法
*
* @param args
*/
public static void main(String[] args) {
// 当前项目路径
String projectPath = System.getProperty("user.dir") + "/boot-business-mybatisplus";
// 模块名
String moduleName = "sys";
// 表名
String[] tableNames = {"sys_user"};
// 代码生成器: 数据源配置
AutoGenerator autoGenerator = new AutoGenerator(buildDataSourceConfig());
// 全局配置
autoGenerator.global(buildGlobalConfig(projectPath));
// 包配置
autoGenerator.packageInfo(buildPackageConfig(projectPath, moduleName));
// 模板配置
autoGenerator.template(buildTemplateConfig());
// 自定义配置
// autoGenerator.injection();
// 策略配置
autoGenerator.strategy(buildStrategyConfig(tableNames));
// 使用Freemarker引擎模板,默认的是Velocity引擎模板(VelocityTemplateEngine)
autoGenerator.execute(new VelocityTemplateEngine());
}
/**
* 数据源配置
*
* @return
*/
private static DataSourceConfig buildDataSourceConfig() {
// 使用元数据查询的方式生成代码
return new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/db_mybatisplus?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false",
"root",
"root")
.build();
}
/**
* 全局配置
*
* @return
*/
private static GlobalConfig buildGlobalConfig(String projectPath) {
return new GlobalConfig.Builder()
// 文件重写
.fileOverride()
// 输出路径
.outputDir(projectPath + "/src/main/java")
// 作者
.author("qiangesoft")
// 开启swagger
// .enableSwagger()
// 日期类型
.dateType(DateType.TIME_PACK)
// 备注日期格式
.commentDate("yyyy-MM-dd")
// 禁止打开文件夹
.disableOpenDir()
.build();
}
/**
* 包配置
*
* @return
*/
private static PackageConfig buildPackageConfig(String projectPath, String moduleName) {
return new PackageConfig.Builder()
// 根包路径
.parent("com.qiangesoft.mybatisplus")
// 模块名
// .moduleName(moduleName)
// 实体包名
.entity("entity")
// 业务接口包名
.service("service")
// 业务实现类包名
.serviceImpl("service.impl")
// mapper接口包名
.mapper("mapper")
// 接口包名
.controller("controller")
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper/"))
.build();
}
/**
* 模板配置
*
* @return
*/
private static TemplateConfig buildTemplateConfig() {
return new TemplateConfig.Builder()
.disable(TemplateType.ENTITY)
// 实体模板
.entity("/templates/entity.java")
// 业务接口模板
.service("/templates/service.java")
// 业务实现类模板
.serviceImpl("/templates/serviceImpl.java")
// mapper接口模板
.mapper("/templates/mapper.java")
// mapper.xml模板
.mapperXml("/templates/mapper.xml")
// 接口模板
.controller("/templates/controller.java")
.build();
}
/**
* 策略配置
*
* @return
*/
private static StrategyConfig buildStrategyConfig(String[] tableNames) {
return new StrategyConfig.Builder()
// 开启大写命名
.enableCapitalMode()
// 开启跳过视图
.enableSkipView()
// 禁用sql过滤
.disableSqlFilter()
// 表匹配
.addInclude(tableNames)
// 表前缀匹配
// .addTablePrefix("t_", "c_")
// 表后缀匹配
// .addFieldSuffix("_flag")
// 1.entity配置
.entityBuilder()
// 开启链式编程
.enableChainModel()
// 开启lombok
.enableLombok()
// 乐观锁字段
.versionColumnName("version")
// .versionPropertyName("version")
// 逻辑删除字段
.logicDeleteColumnName("deleted")
// .logicDeletePropertyName("deleted")
// 数据库表映射实体命名规则
.naming(NamingStrategy.underline_to_camel)
// 表字段策略
.addTableFills(new Column("create_by", FieldFill.INSERT))
.addTableFills(new Column("create_time", FieldFill.INSERT))
.addTableFills(new Column("update_by", FieldFill.UPDATE))
.addTableFills(new Column("update_time", FieldFill.UPDATE))
// 全局主键类型
.idType(IdType.AUTO)
// 2.controller配置
.controllerBuilder()
// 开启驼峰转连字符
.enableHyphenStyle()
// 开启生成@RestController
.enableRestStyle()
// 3.service配置
.serviceBuilder()
// 4.mapper配置
.mapperBuilder()
// .enableMapperAnnotation()
.build();
}
}
2.4 配置mapper扫描
package com.qiangesoft.mybatisplus;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.qiangesoft.mybatisplus.mapper")
@SpringBootApplication
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
2.5 配置分页插件
package com.qiangesoft.mybatisplus.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;
/**
* mybatis-plus配置
*
* @author qiangesoft
* @date 2024-04-11
*/
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 指定数据库mysql
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 智能,根据实际数据库类型构造分页sql
// interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
2.6 api使用
package com.qiangesoft.mybatisplus.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiangesoft.mybatisplus.entity.SysUser;
import com.qiangesoft.mybatisplus.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 用户信息 前端控制器
* </p>
*
* @author qiangesoft
* @since 2024-04-11
*/
@RestController
@RequestMapping("/sys-user")
public class SysUserController {
@Autowired
private ISysUserService sysUserService;
@GetMapping("/page")
public Page<SysUser> page() {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByDesc(SysUser::getCreateTime);
return sysUserService.page(new Page<>(1, 10), queryWrapper);
}
@GetMapping("/list")
public List<SysUser> list() {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByDesc(SysUser::getCreateTime);
return sysUserService.list(queryWrapper);
}
@GetMapping("/save")
public Boolean save() {
SysUser sysUser = new SysUser();
sysUser.setDeptId(1L);
sysUser.setUserName("zhangsan");
sysUser.setPassword("123456");
sysUser.setNickName("张三");
sysUser.setPhoneNumber("13111111111");
sysUser.setSex("0");
sysUser.setStatus("0");
sysUser.setVersion(1);
sysUser.setDeleted(false);
return sysUserService.save(sysUser);
}
@GetMapping("/saveBatch")
public Boolean saveBatch() {
List<SysUser> sysUserList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
SysUser sysUser = new SysUser();
sysUser.setDeptId(1L);
sysUser.setUserName("zhangsan" + i);
sysUser.setPassword("123456");
sysUser.setNickName("张三" + i);
sysUser.setPhoneNumber("1311111111" + i);
sysUser.setSex("0");
sysUser.setStatus("0");
sysUser.setVersion(1);
sysUser.setDeleted(false);
sysUserList.add(sysUser);
}
return sysUserService.saveBatch(sysUserList);
}
@GetMapping("/remove")
public Boolean remove() {
LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(SysUser::getId, 1);
return sysUserService.remove(updateWrapper);
}
@GetMapping("/removeById")
public Boolean removeById() {
return sysUserService.removeById(1);
}
@GetMapping("/removeBatchByIds")
public Boolean removeBatchByIds() {
return sysUserService.removeBatchByIds(Collections.singletonList(1));
}
@GetMapping("/update")
public Boolean update() {
LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(SysUser::getId, 1)
.eq(SysUser::getPhoneNumber, "13222222222");
return sysUserService.update(updateWrapper);
}
@GetMapping("/updateById")
public Boolean updateById() {
SysUser sysUser = new SysUser();
sysUser.setId(1L);
sysUser.setPhoneNumber("13222222222");
return sysUserService.updateById(sysUser);
}
@GetMapping("/updateBatchById")
public Boolean updateBatchById() {
List<SysUser> sysUserList = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
SysUser sysUser = new SysUser();
sysUser.setId((long) i);
sysUser.setPhoneNumber("1511111111" + i);
sysUserList.add(sysUser);
}
return sysUserService.updateBatchById(sysUserList);
}
/**
* 常用的sql方法
*/
private void demoSql() {
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper
// 最前的sql
.first("")
// 查询字段
.select(SysUser::getId, SysUser::getUserName, SysUser::getPhoneNumber)
// 等于
.eq(SysUser::getId, 1)
// 不等于
.ne(SysUser::getId, 0)
// 模糊查询
.like(SysUser::getNickName, "张")
// 左模糊查询 '%*'
.likeLeft(SysUser::getNickName, "张")
// 右模糊查询 '*%'
.likeRight(SysUser::getNickName, "张")
// 大于等于
.ge(SysUser::getCreateTime, LocalDateTime.now())
// 小于等于
.le(SysUser::getUpdateTime, LocalDateTime.now())
// 大于
.gt(SysUser::getCreateTime, LocalDateTime.now())
// 小于
.lt(SysUser::getCreateTime, LocalDateTime.now())
// 介于之间
.between(SysUser::getCreateTime, LocalDateTime.now().minusDays(7), LocalDateTime.now())
// 不介于之间
.notBetween(SysUser::getCreateTime, LocalDateTime.now().minusDays(7), LocalDateTime.now())
// in
.in(SysUser::getId, 1)
// not in
.notIn(SysUser::getId, 3)
// 为空
.isNull(SysUser::getDeptId)
// 不为空
.isNotNull(SysUser::getUserName)
// 和
.and(i -> i.eq(SysUser::getUserName, "李白")
// 或
.or()
.ne(SysUser::getDeleted, true))
// 倒序
.orderByDesc(SysUser::getCreateTime)
// 正序
.orderByAsc(SysUser::getId)
// 存在
.exists("select id from table where age = 1")
// 函数
.func(null)
// 分组
.groupBy(SysUser::getDeptId)
// 过滤
.having("sum(age) > 100")
// 拼接sql
.apply("")
// 最后的sql
.last("limit 1")
;
System.out.println(queryWrapper.getTargetSql());
}
}