MP 基于 MyBatis 的拦截器(Interceptor)实现查询缓存,核心是拦截StatementHandler的查询方法。自定义拦截器,在查询执行前,根据 SQL、参数、分页信息生成唯一缓存 Key,先查 Redis/Caffeine 本地缓存;命中则直接返回缓存数据,不执行数据库查询;未命中则执行 SQL,将结果存入缓存后返回。可配置缓存过期时间、缓存白名单,通过注解标记需要缓存的方法。拦截器无侵入性,不改动业务代码,配合 MP 的查询 Wrapper 使用,大幅降低数据库查询压力,适合读多写少的高频查询场景。
MP 通过自定义拦截器 + 字段注解实现字段级权限。先定义权限注解,标记字段的访问角色;编写拦截器拦截ResultSetHandler,在结果集封装时,获取当前登录用户角色,过滤无权限的字段,不赋值或置空。也可在查询阶段,通过动态 SQL 拦截器,修改查询语句,剔除无权限的查询列。还能结合 MP 的ResultHandler自定义结果处理,适配不同角色的字段可见性。该方案轻量灵活,无需修改业务 SQL,满足后台管理、数据权限精细化管控的需求。
MP 结合dynamic-datasource-spring-boot-starter实现动态数据源,同一事务内切换核心是关闭事务内的数据源缓存。默认 Spring 事务会绑定数据源,需配置参数strict: false,允许事务内切换数据源;使用@DS注解标记数据源,配合@Transactional事务注解。底层通过 ThreadLocal 存储当前数据源标识,拦截器在 SQL 执行前切换数据源。注意:仅支持非分布式事务,同一事务内多数据源操作无法保证原子性,强一致需引入 Seata 等分布式事务框架,兼顾灵活性和数据安全。
MP 负责数据库的 CRUD 与数据同步,ES 负责全文检索。实现方案:数据新增 / 更新时,通过 MP 的拦截器或 AOP,同步数据到 ES;全文搜索请求直接查询 ES,获取主键 ID 后,用 MP 批量查询数据库返回完整数据。复杂查询:ES 做分词、模糊、高亮查询,MP 处理关联数据、字段过滤。可通过 MQ 异步同步数据,避免同步延迟影响业务。MP 保障数据持久化,ES 提供毫秒级全文搜索,两者结合,兼顾数据可靠性和检索性能,适配商品、文章、日志等搜索场景。
MP 3.5.0+ 支持 **@TableName+@TableId实现复合主键,核心用法:实体类上无需单个@TableId,将多个字段标记为主键属性;配置文件指定主键生成器,或使用@KeySequence自定义序列。也可通过自定义主键生成器 **,重写IdentifierGenerator接口,组合多个字段生成复合主键。在 Mapper 接口中,继承BaseMapper时指定实体类,MP 自动识别复合主键,支持 select、update、delete 等操作。复合主键适配联合唯一标识的表结构,无侵入、配置简单,满足老旧业务表的适配需求。
MP 本身不提供分布式事务,需整合第三方框架,核心注意事项:多数据源 / 微服务场景禁用本地事务;整合 Seata AT/TCC 模式,MP 的 CRUD 操作自动参与分布式事务;避免跨库长事务,减小锁粒度;MP 的乐观锁可配合分布式事务,减少冲突;分布式事务下,禁用本地缓存、避免数据不一致;软删除、自动填充等 MP 功能,需在事务提交后执行;监控事务状态,处理超时回滚。核心原则:MP 只负责数据操作,分布式事务由专业框架管控,保证数据最终一致性。
CQRS 分查询端和命令端,MP 完美适配。命令端:用 MP 的增删改方法,操作主库,处理写入业务,配合乐观锁、事务保证数据一致性。查询端:用 MP 的查询 Wrapper、分页插件,操作从库,实现读写分离;复杂查询结合 ES、多表联查,专门处理读请求。通过动态数据源切换主从库,命令和查询分离,互不影响。MP 的轻量 CRUD 简化代码,CQRS 提升系统并发性能,适合高并发、读写比例悬殊的微服务架构,代码结构清晰、易于维护。
微服务下 MP 通过事件驱动 + 分布式事务保证数据一致。写入数据时,MP 执行本地事务后,发送 MQ 消息,其他服务消费消息同步数据;强一致场景用 Seata 整合 MP,实现分布式事务;通过 MP 的乐观锁控制并发更新,避免数据覆盖;多服务共享的公共数据,用 MP 的字段自动填充、软删除统一规范;跨服务查询用 Feign+MP 分页,保证数据格式统一。MP 简化单服务数据操作,配合事件、分布式事务,实现微服务间数据最终一致性,适配主流微服务架构。
MP 数据脱敏有两种方案:注解 + 拦截器和类型处理器。自定义@Desensitize脱敏注解,标记手机号、身份证等字段;编写ResultSetHandler拦截器,查询结果封装时,根据注解类型自动脱敏(隐藏中间字符)。也可自定义TypeHandler,查询时自动脱敏,写入时存储原文。还能通过 MP 的LambdaQueryWrapper过滤敏感字段。脱敏无侵入、配置简单,支持自定义脱敏规则,满足金融、政务等数据隐私合规要求,不影响原始数据存储。
MP 结合动态数据源实现读写分离,核心策略:主库写、从库读。用@DS("master")标记增删改方法,绑定主库;@DS("slave")标记查询方法,绑定从库。MP 的查询、分页、统计全部走从库,写入操作走主库,通过拦截器自动切换数据源。配合负载均衡轮询从库,分散读压力;主从延迟场景,强制关键查询走主库。MP 无需改动业务 SQL,只需注解切换数据源,实现低侵入读写分离,提升系统读性能,适配高并发查询业务。
MP 通过软删除 + 分表 + 自动填充管理历史数据。开启软删除,历史数据标记删除状态,不物理删除;按时间 / 业务分表,用 MP 动态表名插件,自动路由到历史表;通过自动填充记录数据创建、更新、删除时间,追溯数据变更。编写定时任务,用 MP 批量将过期数据迁移到历史表;查询时通过 Wrapper 过滤有效数据,历史数据单独查询。MP 简化历史数据的迁移、查询、删除操作,保证业务表性能,实现冷热数据分离。
MP 大数据优化核心:减少 SQL 交互、降低数据库压力。批量操作使用 MP 官方批量插入 / 更新器,禁止循环单条操作;开启分页插件,禁止全表查询;使用复合索引,配合 LambdaWrapper 精准查询;动态表名分表,拆分大表;禁用 select *,只查询需要的字段;开启 MyBatis 二级缓存、本地缓存;大数据量删除用分批删除,避免长事务;关闭不必要的自动填充、乐观锁。优化后,批量操作性能提升 10 倍以上,适配百万、千万级数据处理场景。
MP 原生支持枚举类型,条件查询无需手动转换。实体枚举字段实现IEnum接口,或用@EnumValue标记数据库存储值;查询时,直接用枚举对象作为参数,LambdaWrapper 会自动转换为数据库存储值。也可配置全局枚举处理器,统一处理枚举映射。支持等于、in、not in 等条件查询,无需手动处理枚举与数据库值的转换,代码简洁、避免类型错误,适配状态、类型等枚举字段的条件筛选。
MP 基于 MyBatis 拦截器实现全局操作拦截,自定义拦截器实现Interceptor接口,指定拦截StatementHandler(SQL 执行)、ParameterHandler(参数)、ResultSetHandler(结果集)。在plugin方法中注册拦截器,配置到 Spring 容器。可全局拦截增删改查,实现数据审计、权限控制、SQL 监控、字段过滤等功能。拦截器支持排序,可多个拦截器组合使用。全局拦截无侵入、灵活扩展,不修改业务代码,统一处理全局通用逻辑。
MP 大量删除优化核心:分批删除 + 避免长事务 + 物理删除。禁止单条循环删除,用deleteBatchIds批量删除;超大数据量,分页分批删除,每批提交事务,避免锁表;软删除场景,直接用 update 批量更新删除标记;关闭不必要的插件(乐观锁、填充),提升速度;通过 Wrapper 精准过滤删除数据,减少扫描行数。优化后,删除速度大幅提升,避免数据库卡顿、事务超时,适配大批量数据清理场景。
MP 结合 dynamic-datasource 自动处理多数据源事务,核心:本地事务单数据源,分布式事务用 Seata。单事务内操作一个数据源,Spring 本地事务自动管理;跨数据源事务,默认不保证一致性,需整合 Seata,MP 的 Mapper 自动参与分布式事务。配置@Transactional(rollbackFor = Exception.class),配合@DS切换数据源,框架自动管理事务提交 / 回滚。无需手动处理事务连接,自动适配多数据源,简单业务用本地事务,强一致用分布式事务。
乐观锁:MP 通过@Version注解实现,实体类添加 version 字段,更新时自动版本 +1,版本不匹配则更新失败,无锁竞争,适合高并发读场景。悲观锁:MP 的QueryWrapper使用last("for update")添加行锁,锁定查询数据,其他事务等待,适合高并发写、强一致场景。乐观锁无侵入、性能高;悲观锁简单可靠、并发低。MP 自动处理乐观锁逻辑,无需手写 SQL,两种锁适配不同并发业务,灵活选择。
MP 分页插件基于MyBatis 拦截器实现,拦截StatementHandler的查询方法。拦截到查询 SQL 后,根据分页参数(pageNum、pageSize),自动拼接count查询总条数,再拼接limit分页语句,执行分页查询。封装结果为IPage对象,包含总条数、总页数、当前页数据。插件支持多种数据库(MySQL、Oracle、PostgreSQL),自动适配方言;支持逻辑分页、物理分页,可配置分页溢出处理、count 查询优化。无侵入、自动拼接 SQL,简化分页开发。
MP 通过动态表名插件实现,自定义TableNameHandler,重写dynamicTableName方法,根据参数、线程变量动态替换表名。配置插件到 MyBatisPlus 拦截器,实体类用@TableName指定原始表名,执行 SQL 时自动替换为动态表名。适用场景:分表、多租户、历史表。支持按时间、用户 ID、租户 ID 分表,无需手写动态 SQL,无侵入、配置简单,适配大表分表、多租户数据隔离。
MP 批量插入优化:官方批量插入器 + 批处理 + 关闭无用功能。使用SqlSessionFactory开启批处理模式,或用 MP 提供的BatchInsertMapper;禁止循环单条插入,批量提交大小设为 1000-5000;关闭自动填充、乐观锁、二级缓存;配置 JDBC 参数rewriteBatchedStatements=true,开启 MySQL 批处理。优化后,百万级数据插入速度提升几十倍,避免事务超时、数据库压力过大,是大批量数据导入的最优方案。
MP 通过自定义 TypeHandler实现字段加解密。编写EncryptTypeHandler,写入时加密字段,查询时解密字段;实体类字段用@TableField(typeHandler = EncryptTypeHandler.class)绑定处理器。支持 AES、RSA 等加密算法,密钥配置在配置文件。也可通过拦截器实现加解密。加密对业务透明,存储密文、展示明文,保障敏感数据(密码、身份证)安全,满足数据合规要求,不影响正常 CRUD 操作。
MP 软删除通过 **@TableLogic** 注解实现,实体类添加删除标记字段(0 未删、1 已删)。配置全局软删除参数,指定未删 / 已删值。MP 的 CRUD 方法自动拼接软删除条件,查询时过滤已删数据,删除时更新标记而非物理删除。支持批量软删除、条件软删除,可查询已删除数据(自定义 Wrapper)。软删除保留历史数据,方便数据恢复,无需手写过滤条件,全局生效,适配所有业务表。
引入 dynamic-datasource 依赖,配置文件定义主从、多库数据源;启动类注解@EnableDynamicDataSource开启功能。使用@DS("数据源名称")注解标记类 / 方法,切换数据源;默认数据源可配置。框架通过拦截器自动切换,无需手动获取连接。支持负载均衡、分组数据源、事务内切换(非强一致)。配置简单、无侵入,适配多租户、读写分离、多业务库场景,是 MP 多数据源的标准方案。
MP 多租户有三种方案:独立数据库、独立 Schema、共享表 + 租户 ID。推荐共享表方案:通过租户拦截器,自动在所有查询 / 写入 SQL 中拼接租户 ID 条件;实体类添加租户 ID 字段,自动填充。动态表名 + 独立 Schema 适配隔离性要求高的场景。MP 的租户插件无侵入,自动处理租户条件,无需业务代码手写过滤,支持多种隔离模式,快速构建 SaaS 多租户系统。
MP 通过 **@TableField(fill = FieldFill.INSERT/UPDATE/INSERT_UPDATE)** 实现自动填充。自定义MetaObjectHandler,重写insertFill和updateFill方法,为创建时间、更新时间、创建人等字段自动赋值。配置填充处理器到 Spring 容器,全局生效。支持自定义填充规则、条件填充,无需业务代码赋值,统一规范公共字段,减少重复代码,保证数据完整性。
MP 查询优化:索引优化 + 精准查询 + 缓存 + 分表。为 where/order by 字段建索引,用 LambdaWrapper 避免全表查询;使用覆盖索引,只查需要字段;开启 MyBatis 二级缓存、本地缓存;大数据表分表,动态表名路由;分页查询替代全表查询;禁用 select *;复杂查询用多表联查替代子查询;读写分离,查询走从库。结合 MP 插件和 SQL 优化,查询性能成倍提升,适配高并发查询场景。
MP 多表联查两种方案:注解 SQL和自定义 Wrapper。在 Mapper 方法上用@Select手写 JOIN SQL,返回自定义 DTO;也可通过QueryWrapper连表查询,配合association、collection映射关联对象。复杂联查推荐使用 MyBatis 的 XML 映射文件,MP 兼容原生 MyBatis 所有功能。支持一对一、一对多、多对多联查,分页、条件查询无缝衔接,兼顾 MP 的简洁和原生 MyBatis 的灵活。
MP 本身无事务管理,基于 Spring 事务机制工作。通过@Transactional注解开启事务,Spring AOP 拦截方法,创建数据库连接,开启事务;方法正常执行则提交,异常则回滚。MP 的 Mapper 操作使用 Spring 管理的连接,自动参与事务。多数据源用 dynamic-datasource 适配,分布式事务用 Seata。事务传播行为、隔离级别、回滚规则完全遵循 Spring 规范,MP 仅负责数据操作,事务由 Spring 统一管控,稳定可靠。
MP 支持原生 MyBatis 注解,在 Mapper 接口方法上使用@Select、@Update、@Delete、@Insert手写复杂 SQL。支持@Results映射结果集,@Param传递参数,配合 OGNL 表达式动态拼接 SQL。复杂查询(多表联查、分组聚合、子查询)直接用注解编写,无需 XML 文件。MP 的 Wrapper 可与注解 SQL 结合,灵活构建查询条件,兼顾简洁性和复杂 SQL 的支持,满足各类业务查询需求。
MP 高级映射:@TableField指定列名、是否查询、是否存在、类型处理器;@TableId指定主键策略、主键列;@Version乐观锁;@TableLogic软删除;@EnumValue枚举映射;@Desensitize脱敏。支持字段忽略(exist=false)、非数据库字段(exist=false)、自定义类型处理器、字段填充。自动适配驼峰命名转下划线,全局配置映射规则。高级用法无侵入,精细化控制字段映射,适配各种复杂表结构。
物理分页:MP 分页插件,自动拼接 limit,数据库层面分页,性能高,生产环境必用。逻辑分页:MyBatis 原生RowBounds,查询全表数据后内存分页,性能极差,仅用于小数据量。配置分页插件,注入MybatisPlusInterceptor,使用Page对象实现物理分页。禁止使用逻辑分页,物理分页配合索引,百万级数据分页无压力,MP 自动处理分页逻辑,简化开发。
MP 多版本控制基于乐观锁 + 历史表实现。用@Version实现数据行版本控制,更新失败重试;数据变更时,通过拦截器将旧版本数据插入历史表,保留所有版本。查询时可指定版本号,查询历史数据。适配需要数据回溯、版本管理的业务(合同、配置文件),无侵入、自动记录版本,保证数据可追溯,满足审计、合规需求。
MP 跨库查询:动态数据源 + 注解 SQL。配置多个数据源,用@DS切换;跨库联查在 SQL 中直接写库名.表名,执行 JOIN 查询。也可通过 postgres_fdw 等外部表,MP 映射为实体类查询。微服务跨库查询用 Feign 远程调用,MP 分页处理结果。MP 兼容原生跨库 SQL,配合动态数据源,无需额外开发,适配同实例多库、异构库查询场景。
MP 自定义 SQL 函数:数据库定义函数,MP 中直接在 Wrapper 的apply、last方法中调用;或在注解 SQL、XML 中直接使用函数。自定义拦截器,将 Java 方法映射为 SQL 函数,自动替换。支持 MySQL、PG 自定义函数,配合查询条件使用,比如自定义加密、计算函数。无需修改框架源码,直接调用,适配业务专属的 SQL 函数需求。
MP 复合主键:3.5.0 以上版本,实体类多个字段用@TableId标记,或实现Serializable接口作为联合主键。Mapper 继承BaseMapper<实体类>,MP 自动识别复合主键,支持 selectById、updateById、deleteById 操作。也可自定义主键生成器,适配联合主键生成规则。配置简单,兼容老旧业务表的复合主键结构,满足特殊表设计的 CRUD 需求。
MP 批量更新优化:分批更新 + 批处理 + 关闭无用插件。使用updateBatchById批量更新;超大数据量分批提交,每批 1000 条;开启 JDBC 批处理参数;关闭乐观锁、自动填充(按需开启);用条件更新替代单条更新。禁止循环单条更新,减少事务交互。优化后,批量更新性能提升数十倍,避免数据库锁表、事务超时,适配大批量数据更新场景。
MP 用 **@Query 注解 + 动态 SQL** 实现,自定义查询注解,标记字段的条件(=、like、in);编写拦截器,根据注解自动构建 LambdaWrapper。也可直接在 Mapper 上用@Select结合 OGNL 表达式,动态拼接多条件 SQL。支持动态条件、组合条件、模糊查询,无需手写 Wrapper,注解驱动开发,代码简洁,适配前端动态传参的复杂查询场景。
MP 长事务优化:拆分长事务为短事务;减小事务锁粒度,只包裹核心写操作;查询操作移出事务,避免长时间占用连接;批量操作分批提交,避免大事务;禁用分布式事务中的本地缓存;使用乐观锁替代悲观锁,减少锁等待;异步处理非核心逻辑,缩短事务执行时间。长事务会导致连接占用、锁竞争,优化后提升系统并发性能,避免事务超时。
MP 基于 MyBatis 拦截器扩展,自定义Interceptor实现插件,拦截 SQL 执行、参数、结果集。可实现数据审计、SQL 监控、字段加密、权限控制、多租户等功能。通过@Component注册插件,配置执行顺序。MP 官方提供分页、乐观锁、动态表名等插件,自定义插件与官方插件兼容。无侵入、灵活扩展,满足框架之外的个性化业务需求。
MP 提供LambdaQueryWrapper、LambdaUpdateWrapper,用 Lambda 方法引用指定字段,避免硬编码字段名。比如wrapper.eq(User::getName, "张三"),编译时检查字段合法性,防止字段名写错。支持链式调用,拼接等于、大于、like、in 等条件,动态构建查询语句。Lambda 查询代码简洁、类型安全、易于维护,是 MP 推荐的查询方式。
实体类创建时间字段加@TableField(fill = FieldFill.INSERT),更新时间字段加@TableField(fill = FieldFill.INSERT_UPDATE)。自定义MetaObjectHandler,在insertFill中设置 createTime,updateFill中设置 updateTime。注册为 Spring Bean,全局自动生效。无需手动赋值,MP 自动填充时间,支持 LocalDateTime、Date 类型,统一管理公共时间字段,减少重复代码。
实体类添加 version 字段,标注@Version注解,指定版本类型(int/long)。MP 自动在更新 SQL 中拼接version = ?,条件version = 旧版本,更新成功版本号 +1。可自定义版本号生成规则,重写乐观锁插件逻辑。注解配置简单,无侵入,自动处理版本校验,高并发下避免数据覆盖,适合订单、库存等并发更新场景。
复杂联查优化:建立联合索引,覆盖查询 / 排序字段;小表驱动大表,优化 JOIN 顺序;** 禁用 select ***,只查需要字段;分页查询,减少数据返回;拆分复杂查询,用临时表 / 子查询优化;开启查询缓存;读写分离,联查走从库。配合 MP 的 Wrapper,避免全表扫描,索引优化后,联查性能提升数倍,适配多表复杂业务查询。
通过拦截器 + 动态配置实现,拦截ResultSetHandler,根据用户权限、配置文件,动态过滤结果字段。或在 Wrapper 中使用select方法,动态指定查询列,不查询不需要的字段。也可自定义ResultHandler,手动封装结果,剔除敏感 / 无用字段。动态过滤无侵入,适配不同角色、不同场景的字段展示需求,减少数据传输,提升查询性能。
MP 枚举处理:实现IEnum接口,getValue返回数据库存储值;或用@EnumValue标记存储字段,@JsonValue标记返回值。配置全局枚举处理器,自动映射枚举与数据库值。增删改查直接使用枚举对象,无需手动转换。支持条件查询、自动填充、序列化,代码简洁、类型安全,适配状态、类型等枚举字段,避免魔法值。
使用LambdaWrapper 链式调用,拼接复合条件,支持 and/or 嵌套,逻辑清晰。动态条件用condition参数,满足条件才拼接 SQL。复杂查询用nested嵌套 Wrapper,apply自定义 SQL 片段。Wrapper 避免手写 SQL,编译时检查字段,动态拼接条件,代码简洁易读。配合 Lambda 表达式,彻底杜绝字段名硬编码,是复合查询的最优方案。
自定义审计拦截器,拦截增删改操作,自动记录操作人、操作时间、操作类型、IP、旧值 / 新值。通过MetaObjectHandler填充操作人、时间,拦截器记录变更日志,存入审计表。MP 插件无侵入,自动审计所有数据操作,无需业务代码处理,满足金融、政务等系统的审计合规要求,数据操作全程可追溯。
MP 整合Caffeine 本地缓存 +Redis 分布式缓存。开启 MyBatis 二级缓存,自定义缓存实现;自定义查询拦截器,缓存查询结果;用@Cacheable注解标记查询方法。缓存 Key 由 SQL、参数、分页组成,设置过期时间。写操作时删除 / 更新缓存,保证数据一致。缓存适配读多写少场景,大幅降低数据库压力,查询响应时间从毫秒级降至微秒级。
多租户场景用动态表名插件,根据租户 ID 生成独立表(如 user_tenant1、user_tenant2)。自定义TableNameHandler,获取当前租户 ID,拼接表名。MP 执行 SQL 时自动替换为租户专属表,实现数据物理隔离。无需手写分表 SQL,自动路由,隔离性最高,适配对数据隔离要求严格的 SaaS 系统,配合租户拦截器,双重保障数据安全。
在 Mapper 接口上用@Update注解编写批量更新 SQL,配合<foreach>标签批量更新;或使用 MP 的@Param传递集合,注解 SQL 批量处理。也可通过SqlSession批处理模式,注解标记批处理方法。注解 SQL 无需 XML,简洁高效,配合 JDBC 批处理参数,性能接近原生批量更新。适合固定规则的大批量更新,简化代码、提升更新速度。