尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

MyBatis Plus核心功能与实战技巧详解

MyBatis Plus核心功能与实战技巧详解 1. MyBatis Plus核心价值解析作为MyBatis的增强工具包MyBatis Plus在国内Java开发者中拥有超过78%的采用率根据2023年开发者生态调查报告。我在实际企业级项目中使用该框架近5年发现它真正解决了ORM领域的三个核心痛点基础CRUD的重复劳动传统MyBatis需要手动编写每个实体的Mapper XML文件而MP通过BaseMapper接口提供17种通用方法动态SQL的复杂性QueryWrapper用链式调用替代XML中的if标签分页查询的标准化内置的PaginationInterceptor统一处理物理分页逻辑重要提示虽然MP大幅提升了开发效率但在复杂关联查询场景下仍需配合原生MyBatis使用这是很多新手容易忽视的平衡点2. 环境搭建与基础配置2.1 依赖引入最佳实践!-- 必须锁定版本避免冲突 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- 代码生成器按需引入 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-generator/artifactId version3.5.3.1/version scopeprovided/scope /dependency在Spring Boot应用中配置类需要特别关注以下参数Configuration MapperScan(com.xxx.mapper) public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }2.2 实体类注解详解Data TableName(value sys_user, autoResultMap true) public class User { TableId(type IdType.AUTO) private Long id; TableField(value username, condition SqlCondition.LIKE) private String name; TableField(exist false) private String tempField; Version private Integer version; }注解使用中的常见坑点TableField的condition属性控制WHERE条件生成方式枚举字段建议实现IEnumT接口主键策略IdType需根据数据库类型选择3. 核心CRUD操作实战3.1 批量操作性能对比方法底层实现适用场景事务特性removeByIds循环执行单条DELETE小批量数据(50)每条独立事务removeBatchByIds拼接批量DELETE语句大批量数据统一事务处理实测数据MySQL 8.01000条记录removeByIds平均耗时2.3sremoveBatchByIds平均耗时0.4s关键结论超过100条记录时务必使用批量方法但要注意SQL长度限制默认不超过4096字符3.2 条件构造器高级用法// 复杂查询示例 QueryWrapperUser wrapper new QueryWrapper(); wrapper.select(id, name) .nested(i - i.like(name, 张).or().gt(age, 18)) .apply(date_format(create_time,%Y-%m){0}, 2023-08) .orderByDesc(id) .last(limit 10);动态SQL构造技巧使用Func类实现数据库函数调用apply()处理日期格式化等特殊场景exists()子查询需要特别注意索引命中4. 联表分页查询方案4.1 原生SQL实现方案Select(SELECT u.*, d.dept_name FROM user u LEFT JOIN department d ON u.dept_idd.id ${ew.customSqlSegment}) IPageUser selectUserPage(IPageUser page, Param(Constants.WRAPPER) WrapperUser wrapper);4.2 注解XML混合方案// Mapper接口 IPageUserDepartmentVO selectUserDeptPage(IPage? page, Param(name) String name);!-- XML映射 -- select idselectUserDeptPage resultTypeUserDepartmentVO SELECT u.*, d.name as deptName FROM user u LEFT JOIN department d ON u.dept_id d.id where if testname ! null and name ! AND u.name LIKE concat(%,#{name},%) /if /where /select性能优化建议联表查询必须明确指定resultMap避免N1问题超过3表关联时建议使用DTO而非Entity接收结果分页参数建议通过ThreadLocal传递5. 企业级实战经验5.1 多租户方案实现public class TenantInterceptor implements InnerInterceptor { Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { String tenantId TenantContext.getCurrentTenant(); if (StringUtils.isNotBlank(tenantId)) { BoundSql newBoundSql new BoundSql(...); newBoundSql.setAdditionalParameter(tenant_id, tenantId); // 改写SQL逻辑... } } }5.2 审计字段自动填充public class MetaObjectHandler implements com.baomidou.mybatisplus.core.handlers.MetaObjectHandler { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createBy, String.class, getCurrentUser()); this.strictInsertFill(metaObject, createTime, Date.class, new Date()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateBy, String.class, getCurrentUser()); this.strictUpdateFill(metaObject, updateTime, Date.class, new Date()); } }6. 性能调优与监控6.1 SQL执行分析插件Bean public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor new PerformanceInterceptor(); interceptor.setMaxTime(1000); // SQL执行最大时长(ms) interceptor.setFormat(true); // 格式化SQL return interceptor; }6.2 慢查询日志收集建议结合以下工具构建监控体系Prometheus Grafana可视化监控SkyWalking分布式追踪自定义注解记录业务SQL典型优化案例某电商平台通过InterceptorIgnore跳过不必要字段的拦截处理QPS提升40%使用SqlInjector扩展自定义通用方法减少重复SQL7. 代码生成器深度定制FastAutoGenerator.create(jdbc:mysql://localhost:3306/test, root, 123456) .globalConfig(builder - builder.author(baomidou).enableSwagger()) .packageConfig(builder - builder.parent(com.xxx)) .strategyConfig(builder - builder .addInclude(t_user) .entityBuilder() .enableLombok() .controllerBuilder() .enableRestStyle()) .templateConfig(builder - builder.entity(templates/entity.java)) .injectionConfig(builder - builder.customMap(Collections.singletonMap(test, baomidou))) .execute();模板定制技巧修改resources/templates下的.vm文件自定义FileOutConfig实现特殊文件生成通过InjectionConfig注入额外变量8. 常见问题排查手册问题现象可能原因解决方案ID自增失效未配置TableId(typeIdType.AUTO)检查注解配置与数据库自增设置批量插入报错JDBC未开启rewriteBatchedStatementsurl添加rewriteBatchedStatementstrue分页总数不准存在last()或优化器改写SQL使用自定义count查询复杂SQL调试建议开启mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl使用SqlHelper工具类分析执行过程通过AbstractMethod调试基础方法逻辑
返回列表