MyBatis-Plus入门指南:简化Java数据库开发
1. 项目概述作为一名长期奋战在一线的Java开发者我深知数据库操作在业务开发中的重要性。传统MyBatis虽然灵活但每次都要手动编写XML映射文件和SQL语句对于简单的CRUD操作来说实在太过繁琐。直到遇见了MyBatis-Plus这个MyBatis的增强工具彻底改变了我的开发方式。最近在团队内部做技术分享时我发现很多刚接触MyBatis-Plus的同事特别是那些SQL基础不太扎实的开发者经常会被一些基础问题困扰如何快速实现增删改查条件查询该怎么写分页功能如何实现这些问题看似简单但如果没有掌握正确的方法确实会让人头疼。2. 环境搭建与配置2.1 依赖引入首先我们需要在项目中引入必要的依赖。如果你使用的是Maven项目在pom.xml中添加以下依赖dependencies !-- MyBatis-Plus Starter -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- MySQL驱动 -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId scoperuntime/scope /dependency !-- Lombok可选但强烈推荐 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies提示建议使用Lombok来简化实体类的getter/setter方法这能让代码更加简洁。2.2 配置文件设置在application.yml中配置数据源和MyBatis-Plus相关设置spring: datasource: url: jdbc:mysql://localhost:3306/your_database?useUnicodetruecharacterEncodingutf8serverTimezoneUTC username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true # 开启下划线转驼峰 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL日志 global-config: db-config: id-type: auto # 主键自增策略 logic-delete-field: is_deleted # 逻辑删除字段 logic-delete-value: 1 # 已删除值 logic-not-delete-value: 0 # 未删除值2.3 启动类配置别忘了在SpringBoot启动类上添加Mapper扫描注解SpringBootApplication MapperScan(com.yourpackage.mapper) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }3. 基础CRUD实现3.1 实体类定义我们先定义一个用户实体类对应数据库中的user表Data TableName(user) public class User { TableId(type IdType.AUTO) private Long id; private String username; private String password; private Integer age; private String email; TableLogic private Integer isDeleted; TableField(fill FieldFill.INSERT) private LocalDateTime createTime; TableField(fill FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; }3.2 Mapper接口创建Mapper接口继承BaseMapper即可获得基础的CRUD方法public interface UserMapper extends BaseMapperUser { // 无需编写任何方法BaseMapper已经提供了基础CRUD功能 }3.3 Service层实现Service层同样可以继承IService接口来简化开发public interface UserService extends IServiceUser { // 可以在这里定义业务特有的方法 } Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { // 基础方法已经由ServiceImpl实现 }3.4 控制器实现现在我们可以轻松实现CRUD接口了RestController RequestMapping(/users) public class UserController { Autowired private UserService userService; // 新增用户 PostMapping public boolean addUser(RequestBody User user) { return userService.save(user); } // 根据ID查询用户 GetMapping(/{id}) public User getUserById(PathVariable Long id) { return userService.getById(id); } // 更新用户 PutMapping public boolean updateUser(RequestBody User user) { return userService.updateById(user); } // 删除用户逻辑删除 DeleteMapping(/{id}) public boolean deleteUser(PathVariable Long id) { return userService.removeById(id); } // 查询所有用户 GetMapping public ListUser listUsers() { return userService.list(); } }4. 条件查询与分页4.1 条件构造器使用MyBatis-Plus提供了强大的条件构造器可以轻松实现复杂查询// 查询年龄大于20且用户名包含张的用户 public ListUser queryUsers() { QueryWrapperUser queryWrapper new QueryWrapper(); queryWrapper.gt(age, 20) .like(username, 张); return userService.list(queryWrapper); } // 更推荐使用Lambda方式避免字段名写错 public ListUser queryUsersLambda() { LambdaQueryWrapperUser lambdaQueryWrapper new LambdaQueryWrapper(); lambdaQueryWrapper.gt(User::getAge, 20) .like(User::getUsername, 张); return userService.list(lambdaQueryWrapper); }4.2 分页查询实现首先需要配置分页插件Configuration public class MyBatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }然后就可以在Service中使用分页查询了public IPageUser pageUsers(int current, int size) { PageUser page new Page(current, size); return userService.page(page); } // 带条件的分页查询 public IPageUser pageUsersWithCondition(int current, int size) { PageUser page new Page(current, size); LambdaQueryWrapperUser queryWrapper new LambdaQueryWrapper(); queryWrapper.gt(User::getAge, 20); return userService.page(page, queryWrapper); }5. 常见问题与解决方案5.1 字段映射问题问题现象数据库字段user_name无法映射到实体类userName查询结果为null。解决方案确保配置文件中开启了map-underscore-to-camel-case: true或者在实体类字段上添加TableField(user_name)注解5.2 逻辑删除失效问题现象调用removeById方法后数据被物理删除而非逻辑删除。解决方案确保实体类中逻辑删除字段添加了TableLogic注解检查配置文件中是否正确配置了逻辑删除字段名和值确保使用的是MyBatis-Plus提供的remove方法而非直接使用MyBatis的delete方法5.3 分页查询不生效问题现象分页查询返回了所有数据而非分页结果。解决方案确认已正确配置分页插件确保查询使用的是page()方法而非list()方法检查是否传入了Page对象作为参数5.4 自动填充不生效问题现象createTime和updateTime字段没有自动填充。解决方案创建一个MetaObjectHandler实现类Component public class MyMetaObjectHandler implements MetaObjectHandler { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createTime, LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } }确保实体类字段上有TableField(fill FieldFill.INSERT)或TableField(fill FieldFill.INSERT_UPDATE)注解6. 高级技巧与最佳实践6.1 代码生成器使用MyBatis-Plus提供了强大的代码生成器可以一键生成Entity、Mapper、Service、Controller等代码public class CodeGenerator { public static void main(String[] args) { FastAutoGenerator.create(jdbc:mysql://localhost:3306/your_db, username, password) .globalConfig(builder - { builder.author(yourname) .outputDir(System.getProperty(user.dir) /src/main/java); }) .packageConfig(builder - { builder.parent(com.yourpackage) .entity(entity) .mapper(mapper) .service(service) .controller(controller); }) .strategyConfig(builder - { builder.addInclude(user, order) // 要生成的表 .addTablePrefix(t_) // 表前缀过滤 .entityBuilder() .enableLombok() .controllerBuilder() .enableRestStyle(); }) .templateEngine(new VelocityTemplateEngine()) .execute(); } }6.2 批量操作优化对于批量插入、更新等操作MyBatis-Plus提供了批量操作方法// 批量插入 ListUser userList new ArrayList(); // 添加多个用户到list boolean success userService.saveBatch(userList); // 批量更新 boolean success userService.updateBatchById(userList);提示批量操作时建议控制每批次的数据量一般1000条左右比较合适避免单次操作数据量过大。6.3 自定义SQL虽然MyBatis-Plus提供了强大的CRUD功能但复杂查询还是需要自定义SQL在Mapper接口中定义方法Select(SELECT * FROM user WHERE age #{age}) ListUser selectUsersOlderThan(Param(age) Integer age);或者在XML中编写复杂SQL!-- UserMapper.xml -- select idselectComplexUsers resultTypecom.yourpackage.entity.User SELECT * FROM user WHERE age #{minAge} AND username LIKE CONCAT(#{keyword}, %) ORDER BY create_time DESC /select7. 性能优化建议合理使用索引为经常查询的字段建立索引特别是WHERE条件和ORDER BY中使用的字段。避免全表扫描尽量使用条件查询限制返回的数据量。分页查询优化对于大数据量表避免使用select *只查询需要的字段。批量操作尽量使用批量插入、更新代替循环单条操作。缓存策略对于不经常变动的数据考虑使用缓存减少数据库访问。SQL监控开发环境开启SQL日志生产环境使用监控工具分析慢查询。在实际项目中我通常会结合以上各种技术根据业务场景选择最合适的实现方式。MyBatis-Plus确实大大简化了数据库操作让开发者能够更专注于业务逻辑的实现。

相关新闻

山西广告标识免费上门测量设计

山西广告标识免费上门测量设计

在山西,广告标识类服务市场需求日益增长。越来越多的企业、商家开始重视自身形象的展示,广告标识作为重要的视觉传达元素,其设计和制作的质量直接影响着品牌的传播效果。而市场上部分广告加工厂推出的免费上门测量设计服务,更是备…

2026/7/22 13:34:15阅读更多 →
经验丰富的3D墙绘施工队

经验丰富的3D墙绘施工队

经验丰富的3D墙绘施工队,打造典彩创意网红3D地面彩绘在当今充满创意与个性的时代,3D墙绘及3D地面彩绘以其独特的视觉效果,成为了城市景观、商业空间、家庭装饰等领域的热门选择。而一支经验丰富的3D墙绘施工队,对于打造出令人惊艳…

2026/7/22 13:34:15阅读更多 →
Python Pygame 太空射击游戏开发:从零到一掌握游戏引擎核心原理

Python Pygame 太空射击游戏开发:从零到一掌握游戏引擎核心原理

1. 项目概述:为什么选择Python和Pygame?如果你对编程感兴趣,尤其是想通过一个看得见、摸得着的项目来巩固Python基础,那么从零开始开发一个太空射击游戏,绝对是个经典且富有成就感的起点。我当年入门时,也做…

2026/7/22 13:32:15阅读更多 →
Tiva™ TM4C129L微控制器深度睡眠功耗管理实战:时钟门控与电源门控详解

Tiva™ TM4C129L微控制器深度睡眠功耗管理实战:时钟门控与电源门控详解

1. 从寄存器手册到实战:理解Tiva™ TM4C129LNCZAD的深度睡眠功耗管理如果你正在用Tiva™ TM4C129LNCZAD这颗Cortex-M4F内核的MCU做物联网终端、便携式医疗设备或者任何对电池续航有苛刻要求的项目,那么功耗管理绝对是你绕不开的核心课题。光靠让CPU进入低…

2026/7/22 14:38:30阅读更多 →
蓝光机挂载网盘实现4K影库共享方案

蓝光机挂载网盘实现4K影库共享方案

1. 项目背景与核心价值 去年入手麦尼塔UDP-800蓝光机时,最让我惊喜的不是它的杜比视界表现,而是那个藏在系统设置里的"SMB共享"功能。作为影音发烧友,手头积攒了上百部4K原盘,传统方式要么得插移动硬盘,要么…

2026/7/22 14:38:30阅读更多 →
馆主崩溃瞬间:学员约不了课,教练课时费对不上,会员流失

馆主崩溃瞬间:学员约不了课,教练课时费对不上,会员流失

前几天和一个开瑜伽馆的朋友吃饭,他叹了口气说:"我最近发现一个事,挺扎心的。"我问怎么了。他说:"我这个月流水做了8万,但月底一算账,利润才1万出头。剩下的钱去哪了?"这不…

2026/7/22 14:38:30阅读更多 →
常开式防火门和常闭式防火门的区别是什么?

常开式防火门和常闭式防火门的区别是什么?

常开式防火门与常闭式防火门是建筑中两种最主要的防火门类型,二者耐火等级一致,但在工作状态、结构配置、适用场景和工作原理上有着本质区别。常闭式防火门结构简单、无需电控设备,依靠防火闭门器和合页实现自动关闭,平时始终处于…

2026/7/22 14:38:30阅读更多 →
艾曲泊帕Eltrombopag覆盖儿童全年龄段慢性ITP治疗【海得康】

艾曲泊帕Eltrombopag覆盖儿童全年龄段慢性ITP治疗【海得康】

慢性免疫性血小板减少症在儿童群体中的年发病率约为4-5/10万,约20%的急性ITP患儿会进展为慢性ITP,病程超过12个月,长期存在皮肤瘀斑、鼻出血等出血风险,传统治疗中儿童长期使用糖皮质激素,会带来生长发育迟缓、骨质疏松…

2026/7/22 14:38:30阅读更多 →
基础版 动手组装一台个人电脑,看完你也是装机高手。

基础版 动手组装一台个人电脑,看完你也是装机高手。

1. 前言:装机前的准备工作 在开始动手组装一台个人电脑之前,做好充分的准备工作是成功的第一步。这不仅能让装机过程更顺畅,也能有效避免因疏忽造成的硬件损坏。 你需要准备的工具和物品: 十字螺丝刀:一把磁性螺丝刀会…

2026/7/22 14:36:30阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →