万网注册域名就可以做网站吗,网站首页建设网站,企业工商信息查询系统官网,翻译建设企业网站目录
简介
安装
Spring Boot2
Spring Boot3
Spring
配置
Spring Boot 工程
Spring 工程
常见注解
条件构造器
流式查询
使用示例
批量操作
使用示例
自定义SQL
Service接口
CRUD
扩展功能
代码生成
安装插件
通用枚举
配置枚举处理器
插件功能
配置示例…目录
简介
安装
Spring Boot2
Spring Boot3
Spring
配置
Spring Boot 工程
Spring 工程
常见注解
条件构造器
流式查询
使用示例
批量操作
使用示例
自定义SQL
Service接口
CRUD
扩展功能
代码生成
安装插件
通用枚举
配置枚举处理器
插件功能
配置示例 简介
MyBatis-Plus 是一个 MyBatis 的增强工具在 MyBatis 的基础上只做增强不做改变为简化开发、提高效率而生。 特性
无侵入只做增强不做改变引入它不会对现有工程产生影响如丝般顺滑损耗小启动即会自动注入基本 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 操作智能分析阻断也可自定义拦截规则预防误操作 安装
Spring Boot2
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.7/version
/dependency
Spring Boot3
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-spring-boot3-starter/artifactIdversion3.5.7/version
/dependency
Spring
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus/artifactIdversion3.5.7/version
/dependency
注意事项 引入 MyBatis-Plus 之后请不要再次引入 MyBatis 以及 mybatis-spring-boot-starter和MyBatis-Spring以避免因版本差异导致的问题。 自3.5.4开始在没有使用mybatis-plus-boot-starter或mybatis-plus-spring-boot3-starter情况下请自行根据项目情况引入mybatis-spring。
配置
Spring Boot 工程
配置 MapperScan 注解
SpringBootApplication
MapperScan(com.baomidou.mybatisplus.samples.quickstart.mapper)
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
大多数的配置都有默认值因此我们都无需配置。但还有一些是没有默认值的例如:
1、实体类的别名扫描包
2、全局id类型
mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto # 全局id类型为自增长
需要注意的是MyBatisPlus也支持手写SQL的而mapper文件的读取地址可以自己配置
mybatis-plus:mapper-locations: classpath*:/mapper/**/*.xml # Mapper.xml文件地址当前这个是默认值。
可以看到默认值是classpath*:/mapper/**/*.xml也就是说我们只要把mapper.xml文件放置这个目录下就一定会被加载。
Spring 工程
配置 MapperScan
bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valuecom.baomidou.mybatisplus.samples.quickstart.mapper/
/bean
调整 SqlSessionFactory 为 MyBatis-Plus 的 SqlSessionFactory
bean idsqlSessionFactory classcom.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBeanproperty namedataSource refdataSource/
/bean
常见注解
1、TableName
用于指定数据库表名。通常与实体类一起使用用于映射数据库表。
TableName注解除了指定表名以外还可以指定很多其它属性 属性 类型 必须指定 默认值 描述 value String 否 表名 schema String 否 schema keepGlobalPrefix boolean 否 false 是否保持使用全局的 tablePrefix 的值当全局 tablePrefix 生效时 resultMap String 否 xml 中 resultMap 的 id用于满足特定类型的实体类对象绑定 autoResultMap boolean 否 false 是否自动构建 resultMap 并使用如果设置 resultMap 则不会进行 resultMap 的自动构建与注入 excludeProperty String[] 否 {} 需要排除的属性名 since 3.3.1
2、TableId 用于标识实体类中的主键字段。可以指定主键的生成策略。
TableId注解支持两个属性 属性 类型 必须指定 默认值 描述 value String 否 表名 type Enum 否 IdType.NONE 指定主键类型
IdType支持的类型有 值 描述 AUTO 数据库 ID 自增 NONE 无状态该类型为未设置主键类型注解里等于跟随全局全局里约等于 INPUT INPUT insert 前自行 set 主键值 ASSIGN_ID 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法) ASSIGN_UUID 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认 default 方法) ID_WORKER 分布式全局唯一 ID 长整型类型(please use ASSIGN_ID) UUID 32 位 UUID 字符串(please use ASSIGN_UUID) ID_WORKER_STR 分布式全局唯一 ID 字符串类型(please use ASSIGN_ID)
这里比较常见的有三种
AUTO利用数据库的id自增长INPUT手动生成idASSIGN_ID雪花算法生成Long类型的全局唯一id这是默认的ID策略
3、TableField 用于指定实体类字段与数据库表字段的映射关系。它可以用于自定义列名、是否插入、更新等。
一般情况下我们并不需要给字段添加TableField注解一些特殊情况除外
1、成员变量名与数据库字段名不一致
如果实体类中的字段名与数据库表中的列名不一致可以使用 TableField 注解来指定数据库中的列名
TableField(value db_column_name)
private String entityFieldName;2、成员变量是以 isXXX 命名
按照 JavaBean 规范如果字段以 is 开头MyBatis-Plus 默认会去掉 is 部分来进行映射。如果数据库字段名与去掉 is 后的变量名不一致需要用 TableField 指定数据库中的列名
TableField(value db_column_name)
private Boolean isActive;3、成员变量名与数据库字段一致但与数据库关键字冲突
如果字段名与数据库中的关键字冲突可以使用反引号 来处理
TableField(value key)
private String key;支持的其它属性如下 属性 类型 必填 默认值 描述 value String 否 数据库字段名 exist boolean 否 true 是否为数据库表字段 condition String 否 字段 where 实体查询比较条件有值设置则按设置的值为准没有则为默认全局的 %s#{%s}参考(opens new window) update String 否 字段 update set 部分注入例如当在version字段上注解update%s1 表示更新时会 set versionversion1 该属性优先级高于 el 属性 insertStrategy Enum 否 FieldStrategy.DEFAULT 举例NOT_NULL insert into table_a(if testcolumnProperty ! nullcolumn/if) values (if testcolumnProperty ! null#{columnProperty}/if) updateStrategy Enum 否 FieldStrategy.DEFAULT 举例IGNORED update table_a set column#{columnProperty} whereStrategy Enum 否 FieldStrategy.DEFAULT 举例NOT_EMPTY where if testcolumnProperty ! null and columnProperty!column#{columnProperty}/if fill Enum 否 FieldFill.DEFAULT 字段自动填充策略 select boolean 否 true 是否进行 select 查询 keepGlobalFormat boolean 否 false 是否保持使用全局的 format 进行处理 jdbcType JdbcType 否 JdbcType.UNDEFINED JDBC 类型 (该默认值不代表会按照该值生效) typeHandler TypeHander 否 类型处理器 (该默认值不代表会按照该值生效) numericScale String 否 指定小数点后保留的位数
条件构造器
MyBatis-Plus 的条件构造器Wrapper确实提供了强大且灵活的功能用于构建各种数据库查询和更新条件。
1. AbstractWrapper
AbstractWrapper 是所有 Wrapper 类的基类定义了构造查询和更新条件的基础方法和属性包括字段、值、操作符等。其他具体的 Wrapper 类如 QueryWrapper、UpdateWrapper、LambdaQueryWrapper 和 LambdaUpdateWrapper都继承自它。
2. QueryWrapper
QueryWrapper 用于构造查询条件支持多种操作符和逻辑组合。可以通过链式调用添加多个查询条件并通过 and 和 or 来组合条件。
QueryWrapperUser queryWrapper new QueryWrapper();
queryWrapper.eq(status, 1).gt(age, 18).or().like(name, John);ListUser users userMapper.selectList(queryWrapper);在上面的例子中eq 表示等于gt 表示大于or 表示逻辑“或”like 表示模糊匹配。
3. UpdateWrapper UpdateWrapper 用于构造更新条件它允许你在更新数据时指定条件。它的使用方法与 QueryWrapper 类似。
UpdateWrapperUser updateWrapper new UpdateWrapper();
updateWrapper.eq(status, 1).set(age, 30).set(name, Updated Name);userMapper.update(null, updateWrapper);在这个例子中set 用于指定需要更新的字段及其新值。
4. LambdaQueryWrapper
LambdaQueryWrapper 允许使用 Lambda 表达式来引用实体类的属性避免了硬编码字段名的问题从而提高了代码的可读性和可维护性。
LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapper();
lambdaQueryWrapper.eq(User::getStatus, 1).gt(User::getAge, 18).or().like(User::getName, John);ListUser users userMapper.selectList(lambdaQueryWrapper);5. LambdaUpdateWrapper
LambdaUpdateWrapper 与 LambdaQueryWrapper 类似但用于构造更新条件。它允许使用 Lambda 表达式来设置更新字段及条件。
LambdaUpdateWrapperUser lambdaUpdateWrapper new LambdaUpdateWrapper();
lambdaUpdateWrapper.eq(User::getStatus, 1).set(User::getAge, 30).set(User::getName, Updated Name);userMapper.update(null, lambdaUpdateWrapper);流式查询
MyBatis-Plus 从 3.5.4 版本开始支持流式查询这使得在处理大数据量时更加高效。流式查询通过 ResultHandler 接口实现可以有效地避免将整个结果集加载到内存中适合用于数据跑批或大规模数据处理的场景。
常用方法
在 ResultHandler 中可以使用以下方法来处理查询结果
getResultObject(): 获取当前数据库中的每一条记录。getResultCount(): 获取当前处理的结果集条数每处理一条记录该计数器会加1计数从1开始。stop(): 停止继续处理结果集相当于在循环中使用 break 语句。
使用示例
以下是官网使用流式查询的示例代码展示了如何结合分页从数据库中拉取数据进行批量处理以及如何获取表中的所有记录进行处理。
// 结合分页按批次从数据库拉取数据出来跑批例如从数据库获取10万记录做数据处理
PageH2User page new Page(1, 100000);
baseMapper.selectList(page, Wrappers.emptyWrapper(), new ResultHandlerH2User() {int count 0;Overridepublic void handleResult(ResultContext? extends H2User resultContext) {H2User h2User resultContext.getResultObject();System.out.println(当前处理第 (count) 条记录: h2User);// 在这里进行你的业务处理比如分发任务}
});// 从数据库获取表所有记录做数据处理
baseMapper.selectList(Wrappers.emptyWrapper(), new ResultHandlerH2User() {int count 0;Overridepublic void handleResult(ResultContext? extends H2User resultContext) {H2User h2User resultContext.getResultObject();System.out.println(当前处理第 (count) 条记录: h2User);// 在这里进行你的业务处理比如分发任务}
});
注意事项
分页查询与流式查询: 在低版本的 MyBatis-Plus 中自定义 ResultHandler 结合分页查询可能会出现问题。解决方案是手动关闭 count 查询资源管理: 使用流式查询时确保数据库连接在操作完成后被正确关闭避免连接泄露问题。性能优化: 流式查询适合于大数据量的场景不适合处理小数据量的查询因其可能引入不必要的复杂性。
批量操作
批量操作是处理大量数据时的一种高效技术它通过一次性执行多个数据库操作来提高效率和性能。常见的批量操作包括
数据插入一次性插入多条记录减少SQL执行次数加快数据写入速度。数据更新同时更新多条记录的特定字段适用于批量修改数据的场景。数据删除快速删除多条记录适合数据清理和用户注销等操作。
功能概览
支持版本3.5.4及以上版本事务控制需手动管理默认关闭执行结果返回批量处理结果帮助判断操作是否成功数据写入取决于代码是否正确执行到flushStatements兼容性支持Spring和非Spring项目异常类型可能会抛出PersistenceException建议对于saveOrUpdate方法建议简单处理新增或更新操作
类结构说明
MybatisBatch?
泛型实际数据类型sqlSessionFactory通过容器获取非Spring容器下需手动初始化dataList批量数据处理列表不能为空
MybatisBatch.Method?
实际为BatchMethod用于简化框架内部操作方法的调用泛型实际Mapper方法参数类型mapperClass具体的Mapper类
BatchMethod?
泛型实际Mapper方法参数类型statementId执行的MappedStatement IDparameterConvert用于数据类型与Mapper方法参数不一致时的转换处理器
使用步骤
创建MybatisBatch实例绑定数据列表和sqlSessionFactory。创建MybatisBatch.Method实例确定执行的Mapper类方法。执行操作将批量参数转换为Mapper方法所需的参数。处理返回值返回ListBatchResult每个BatchResult代表一次MappedStatement的操作结果。
返回值说明
返回类型ListBatchResult返回内容分组存储每次MappedStatement SQL操作的结果。例如批量更新时返回值将根据更新字段的不同分组显示每组记录的更新情况。
使用示例
execute 方法
execute 方法通常用于直接执行批量操作例如批量插入或更新。它通过指定的 SQL 语句执行批量处理。在 MyBatis-Plus 中这通常涉及到使用 SqlSession 执行自定义 SQL。
public void executeBatch(ListMyEntity entities) {SqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH, false);try {MyMapper mapper sqlSession.getMapper(MyMapper.class);for (MyEntity entity : entities) {mapper.insert(entity); // 执行插入操作}sqlSession.commit(); // 提交事务} catch (Exception e) {sqlSession.rollback(); // 回滚事务throw e;} finally {sqlSession.close();}
}saveOrUpdate 方法
saveOrUpdate 方法用于处理批量保存或更新操作自动决定记录是插入还是更新。
注意跨sqlSession下需注意缓存和数据感知问题。
public void saveOrUpdateBatch(ListMyEntity entities) {SqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH, false);try {MyMapper mapper sqlSession.getMapper(MyMapper.class);for (MyEntity entity : entities) {if (entity.getId() null || mapper.selectById(entity.getId()) null) {mapper.insert(entity); // 插入操作} else {mapper.updateById(entity); // 更新操作}}sqlSession.commit(); // 提交事务} catch (Exception e) {sqlSession.rollback(); // 回滚事务throw e;} finally {sqlSession.close();}
}事务处理示例
在 MyBatis-Plus 中事务管理可以通过 Spring 的事务管理器或 MyBatis 的原生事务控制进行。
Spring 事务处理示例
Service
public class MyService {Autowiredprivate MyMapper myMapper;Transactional // 事务注解public void batchProcess(ListMyEntity entities) {for (MyEntity entity : entities) {myMapper.insert(entity); // 执行插入操作}}
}手动事务处理示例
public void manualTransaction(ListMyEntity entities) {SqlSession sqlSession sqlSessionFactory.openSession();try {MyMapper mapper sqlSession.getMapper(MyMapper.class);for (MyEntity entity : entities) {mapper.insert(entity); // 执行插入操作}sqlSession.commit(); // 提交事务} catch (Exception e) {sqlSession.rollback(); // 回滚事务throw e;} finally {sqlSession.close();}
}自定义SQL
sql
-- 1删除数据库drop database if exists test;
-- 2创建数据库create database test;
-- 3修改数据库编码方式和字符集排列顺序alter database test character set utf8 collate utf8_bin;
-- 4使用数据库use test;-- 创建教师表
CREATE TABLE teacher (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,subject VARCHAR(100) NOT NULL
);-- 创建班级表
CREATE TABLE class (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,teacher_id INT,FOREIGN KEY (teacher_id) REFERENCES teacher(id)
);-- 创建学生表
CREATE TABLE student (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,age INT NOT NULL,class_id INT,FOREIGN KEY (class_id) REFERENCES class(id)
);
-- 插入教师数据
INSERT INTO teacher (name, subject) VALUES
(李华, 数学),
(张伟, 物理),
(王芳, 历史);-- 插入班级数据并关联教师
INSERT INTO class (name, teacher_id) VALUES
(数学101, 1), -- 由李华教授
(物理101, 2), -- 由张伟教授
(历史101, 3); -- 由王芳教授-- 插入学生数据并关联班级
INSERT INTO student (name, age, class_id) VALUES
(小明, 15, 1), -- 在数学101班级
(小红, 16, 1), -- 在数学101班级
(小刚, 15, 2), -- 在物理101班级
(小李, 17, 2), -- 在物理101班级
(小华, 16, 3); -- 在历史101班级查询李华教授带的课程班级学生数据
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.mapper.TeacherMapper!-- 查询李华教授带的课程、班级和学生数据 --select idfindTeacherClassesAndStudents resultTypemapSELECTt.name AS teacher_name,c.name AS class_name,s.name AS student_name,s.age AS student_ageFROM teacher tJOIN class c ON t.id c.teacher_idJOIN student s ON c.id s.class_idWHERE t.name 李华/select
/mapperpackage com.example.demo.mapper;import com.example.demo.entity.Teacher;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;/*** p* Mapper 接口* /p** author * since 2024-09-08*/
Mapper
public interface TeacherMapper extends BaseMapperTeacher {ListMapString, Object findTeacherClassesAndStudents();
}package com.example.demo.service.impl;import com.example.demo.entity.Teacher;
import com.example.demo.mapper.TeacherMapper;
import com.example.demo.service.ITeacherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;/*** p* 服务实现类* /p** author * since 2024-09-08*/
Service
public class TeacherServiceImpl extends ServiceImplTeacherMapper, Teacher implements ITeacherService {Autowiredprivate TeacherMapper teacherMapper;public ListMapString, Object getTeacherClassesAndStudents() {return teacherMapper.findTeacherClassesAndStudents();}
}package com.example.demo.controller;import com.example.demo.service.impl.TeacherServiceImpl;
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.util.List;
import java.util.Map;/*** p* 前端控制器* /p** author * since 2024-09-08*/
RestController
RequestMapping(/teacher)
public class TeacherController {Autowiredprivate TeacherServiceImpl teacherService;GetMapping(/classes)public ListMapString, Object getTeacherClassesAndStudents() {return teacherService.getTeacherClassesAndStudents();}
} Service接口
MybatisPlus不仅提供了BaseMapper还提供了通用的Service接口及默认实现封装了一些常用的service模板方法。 通用接口为IService默认实现为ServiceImpl其中封装的方法可以分为以下几类
save新增remove删除update更新get查询单个结果list查询集合结果count计数page分页查询
CRUD
我们先俩看下基本的CRUD接口。
新增 save - 新增单个元素用于新增单个记录。它会根据实体类的字段进行插入操作。 saveBatch - 批量新增用于批量新增多条记录。适合在一次操作中插入多个实体对象提高插入效率。saveOrUpdate - 根据 ID 判断新增或更新如果实体对象的 ID 存在于数据库中则执行更新操作如果 ID 不存在则执行插入操作。saveOrUpdateBatch - 批量的新增或修改批量处理实体对象根据每个对象的 ID 判断是执行插入还是更新操作。
删除
removeById - 根据 ID 删除删除指定 ID 的记录。removeByIds - 批量根据 ID 删除删除多个指定 ID 的记录。removeByMap - 根据 Map 中的条件删除根据 Map 中的键值对作为条件进行删除。remove(WrapperT) - 根据 Wrapper 条件删除使用 Wrapper 对象中定义的条件进行删除。removeBatchByIds 方法已不再支持建议使用 removeByIds 进行批量删除操作。
修改 updateById - 根据 ID 修改根据指定 ID 更新记录。需要提供更新后的实体对象。update(WrapperT) - 根据 UpdateWrapper 修改使用 UpdateWrapper 进行条件更新。需要定义更新的字段和条件。update(T, WrapperT) - 按照实体数据和 Wrapper 修改根据实体对象中的数据和 Wrapper 中的条件进行更新。实体对象中的字段会被更新到符合 Wrapper 条件的记录中。updateBatchById - 根据 ID 批量修改根据多个 ID 批量更新记录。实体对象中的数据会更新到对应的 ID 中。
Get getById - 根据 ID 查询根据指定 ID 获取一条记录。getOne(WrapperT) - 根据 Wrapper 查询使用 Wrapper 条件获取一条记录。如果有多条记录符合条件只会返回其中一条。getBaseMapper - 获取 BaseMapper 实现获取 Service 内的 BaseMapper 实现以便进行自定义 SQL 操作或其他特殊操作。
List listByIds - 根据 ID 批量查询根据多个 ID 获取对应的记录。list(WrapperT) - 根据 Wrapper 条件查询使用 Wrapper 条件获取多条记录。list() - 查询所有获取所有记录。
Count count() - 统计所有记录的数量统计数据库中所有记录的总数。count(WrapperT) - 统计符合 Wrapper 条件的记录数量使用 Wrapper 条件统计符合条件的记录数量。
getBaseMapper getBaseMapper 方法允许在 Service 中直接获取 Mapper 实现以便执行自定义 SQL 查询或操作。
TeacherMapper teacherMapper teacherService.getBaseMapper();
ListTeacher teachers teacherMapper.customQueryMethod();这样可以在 Mapper 中定义自定义的 SQL 方法并通过 getBaseMapper 直接调用。
扩展功能
代码生成
MybatisPlus 提供的代码生成器可以大大简化代码编写工作但使用起来可能有些复杂。推荐的图形化插件能够通过友好的界面完成代码生成简化了配置和操作流程。这样的工具能有效提升开发效率减少手动编写基础代码的工作量。
安装插件
在Idea的plugins市场中搜索并安装MyBatisPlus插件 然后重启你的Idea即可使用。
通用枚举
sql
-- 1删除数据库drop database if exists test;
-- 2创建数据库create database test;
-- 3修改数据库编码方式和字符集排列顺序alter database test character set utf8 collate utf8_bin;
-- 4使用数据库use test;-- 创建教师表
CREATE TABLE teacher (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,subject VARCHAR(100) NOT NULL
);-- 创建班级表
CREATE TABLE class (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,teacher_id INT,FOREIGN KEY (teacher_id) REFERENCES teacher(id)
);-- 创建学生表
CREATE TABLE student (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) NOT NULL,age INT NOT NULL,class_id INT,gender ENUM(Male, Female) NOT NULL,FOREIGN KEY (class_id) REFERENCES class(id)
);-- 插入教师数据
INSERT INTO teacher (name, subject) VALUES
(李华, 数学),
(张伟, 物理),
(王芳, 历史);-- 插入班级数据并关联教师
INSERT INTO class (name, teacher_id) VALUES
(数学101, 1),
(物理101, 2),
(历史101, 3);-- 插入学生数据并关联班级
INSERT INTO student (name, age, class_id, gender) VALUES
(小明, 15, 1, Male),
(小红, 16, 1, Female),
(小刚, 15, 2, Male),
(小李, 17, 2, Male),
(小华, 16, 3, Female);定义通用枚举
public enum Gender {MALE(Male),FEMALE(Female);private final String description;Gender(String description) {this.description description;}public String getDescription() {return description;}
}假设在 Java 中处理这些数据可以在实体类中添加枚举字段
public class Student {private Long id;private String name;private int age;private Long classId;private Gender gender;
}
配置枚举处理器
在application.yaml文件中添加配置
mybatis-plus:configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
插件功能
PaginationInnerInterceptor自动分页自动处理分页查询。TenantLineInnerInterceptor多租户实现多租户功能通过 SQL 查询条件自动添加租户信息。DynamicTableNameInnerInterceptor动态表名允许动态更改 SQL 查询中的表名。OptimisticLockerInnerInterceptor乐观锁实现乐观锁机制避免数据的并发更新冲突。IllegalSQLInnerInterceptorSQL 性能规范检查 SQL 语句的规范性避免不合理的 SQL。BlockAttackInnerInterceptor防止全表更新与删除防止全表更新和删除操作避免误操作。
插件定义顺序
使用多个插件时需要注意插件的定义顺序以确保插件功能的正常运行。通常的顺序如下
多租户TenantLineInnerInterceptor动态表名DynamicTableNameInnerInterceptor分页PaginationInnerInterceptor乐观锁OptimisticLockerInnerInterceptorSQL 性能规范IllegalSQLInnerInterceptor防止全表更新与删除BlockAttackInnerInterceptor
配置示例
下面是一个示例配置演示如何按照顺序注册这些插件
package com.example.demo.Config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** MybatisPlus配置类* 用于配置MybatisPlus的相关插件*/
Configuration
public class MybatisPlusConfig {/*** 配置MybatisPlus拦截器* 拦截器用于处理租户、动态表名、分页、乐观锁、非法SQL和防注入攻击等功能** return 配置好的MybatisPlusInterceptor对象*/Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();// 添加租户拦截器处理多租户场景下的数据隔离interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(/* TenantLineHandler */));// 添加动态表名拦截器支持动态表名interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor(/* DynamicTableNameHandler */));// 添加分页拦截器实现分页功能interceptor.addInnerInterceptor(new PaginationInnerInterceptor());// 添加乐观锁拦截器支持乐观锁机制interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());// 添加非法SQL拦截器防止非法SQL注入interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());// 添加防注入攻击拦截器增强SQL安全性interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());return interceptor;}
}这里我们以分页插件为里来学习插件的用法。
package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;/*** p* * /p** author * since 2024-09-08*/
Data
EqualsAndHashCode(callSuper false)
Accessors(chain true)
TableName(student)
public class Student implements Serializable {private static final long serialVersionUID 1L;TableId(value id, type IdType.AUTO)private Integer id;private String name;private Integer age;private Integer classId;private String gender;
}package com.example.demo.mapper;import com.example.demo.entity.Student;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;/*** p* Mapper 接口* /p** author * since 2024-09-08*/
public interface StudentMapper extends BaseMapperStudent {}package com.example.demo.controller;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Student;
import com.example.demo.service.impl.StudentServiceImpl;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** p* 前端控制器* /p** author* since 2024-09-08*/
RestController
public class StudentController {Autowiredprivate StudentServiceImpl studentService;GetMapping(/students)public PageStudent getStudentsByAge(RequestParam int age,RequestParam(defaultValue 1) int page,RequestParam(defaultValue 10) int size) {return studentService.getStudentsByAge(age, page, size);}
}启动Spring Boot项目后访问以下URL进行分页查询
http://localhost:8080/students?age17page1size10
这将返回年龄为17的学生信息每页10条记录并以JSON格式返回。