妙用MyBatis-Plus,12个实战技巧解锁新知识

文摘   2024-12-26 12:02   陕西  
今天我们来聊聊 MyBatis-Plus,这可是一个能让我们开发更高效、代码更简洁的好工具。
如果你曾经和MyBatis打过交道,那你一定知道它是一款功能强大的 ORM 框架,但也有一些使用上的麻烦。
幸运的是,MyBatis-Plus的出现让这些麻烦都变得不值一提,就像是给了我们一把全新的钥匙,打开了性能和可维护性的“大门”。
今天就跟大家分享12个我觉得特别有用的MyBatis-Plus优化技巧,让你像外婆做羊肉汤一样,煮出一锅既香浓又高效的代码。

1. 避免使用 isNull 判断

问题:MySQL的 NULL 值判断可能会导致索引失效,进而影响查询性能,尤其是在有大量数据的情况下。
推荐做法:如果可以的话,直接用具体的默认值代替 NULL,比如通过 UserStatusEnum.INACTIVE.getCode() 来代替空值判断。
示例代码
// 不推荐的做法
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNull("status");

// 推荐的做法
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", UserStatusEnum.INACTIVE.getCode());
通过这样处理,我们避免了 NULL 比较的问题,数据库查询可以更高效。

2. 明确 select 字段

问题:在不指定字段的情况下查询所有字段,会导致数据量过大,尤其是当表的数据量较大时,性能差、回表严重。
推荐做法:在查询时,明确指定你需要的字段,避免不必要的数据查询和回表。
示例代码
// 不推荐的做法
List<User> users = userMapper.selectList(new QueryWrapper<>());

// 推荐的做法
List<User> users = userMapper.selectList(
    new QueryWrapper<User>().select("id""name""email")
);
通过选择性字段查询,不仅减少了内存占用,还提升了性能。

3. 批量操作方法替代循环

问题:如果你在循环中逐条插入数据,这样会严重影响性能,尤其是数据量大的时候。
推荐做法:使用 MyBatis-Plus 提供的批量操作方法 saveBatch(),提高数据插入效率。
示例代码
// 不推荐的做法:逐条插入
for (User user : userList) {
    userMapper.insert(user);
}

// 推荐的做法:批量插入
userMapper.saveBatch(userList);
批量插入不仅提高了效率,还减少了数据库的负载。

4. 使用 exists 方法代替 inSql 子查询

问题IN 子查询会将所有匹配的数据加载到内存中,特别是当数据量大时,会造成性能瓶颈。
推荐做法:使用 EXISTS 子查询,它更高效,因为数据库会直接基于索引来判断是否存在,避免了将所有数据都加载到内存的情况。
示例代码
// 不推荐的做法:使用 IN 子查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.inSql("id""SELECT id FROM user WHERE status = 'active'");

// 推荐的做法:使用 EXISTS 子查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.exists("SELECT 1 FROM user WHERE status = 'active' AND user.id = user.id");
通过使用 EXISTS,查询会更高效,尤其在大数据量的情况下,性能提升明显。

5. 使用 orderBy 代替 last

问题:直接拼接 SQL 可能引发 SQL 注入风险。比如,你可能写了一个拼接排序的 SQL 语句,结果被不怀好意的人利用了。
推荐做法:使用 MyBatis-Plus 提供的 orderBy 来进行安全排序,避免手动拼接 SQL 字符串。
示例代码
// 不推荐的做法:直接拼接排序字段
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.last("ORDER BY created_at DESC");

// 推荐的做法:使用 orderBy 进行排序
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("created_at");
这样写不仅安全,代码也更加简洁清晰。

6. 使用 LambdaQuery 确保类型安全

问题:手写字段名称容易出错,特别是对于较大的项目,字段名错了就会引发难以排查的错误。
推荐做法:使用 LambdaQueryWrapper 来保证字段名的类型安全,编译时就能发现错误,减少运行时出错的概率。
示例代码
// 不推荐的做法
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name""Tom");

// 推荐的做法:使用 LambdaQueryWrapper
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "Tom");
这样,代码不仅避免了拼写错误,还能提高可维护性。

7. 使用 between 代替 gele

问题:多个条件判断使 SQL 语句变得冗长且难以阅读。
推荐做法:通过 between 来简化 SQL 语句,使条件更为简洁,提升可读性。
示例代码
// 不推荐的做法
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age"18).le("age"30);

// 推荐的做法:使用 between
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age"1830);
通过使用 between,你可以让 SQL 更简洁,逻辑也更加清晰。

8. 排序字段注意索引

问题:如果排序字段没有索引,数据库会进行全表排序,这样会导致性能下降。
推荐做法:确保用于排序的字段有索引,这样查询时数据库可以利用索引进行排序,从而提高性能。

9. 分页参数设置

问题:一次查询过多数据可能导致内存溢出,尤其是数据量较大时。
推荐做法:使用分页查询,控制每次查询的数据量,避免一次性加载过多数据。

10. 条件构造处理 NULL 值

问题:空值条件判断冗余,容易导致无效查询条件。
推荐做法:使用 eq 方法优雅地处理空值,避免无效查询条件的出现。

11. 查询性能追踪

问题:简单的计时方法冗余,无法集中管理性能监控。
推荐做法:使用 try-with-resources 结合自定义的性能追踪工具,优雅地监控查询性能。

12. 枚举类型映射

问题:手动映射枚举值不仅不安全,而且难以维护。
推荐做法:使用 MyBatis-Plus 提供的枚举映射功能,自动处理枚举与数据库值之间的转换。
通过这些技巧的运用,我们可以让代码变得更加简洁、高效和易于维护。MyBatis-Plus的好处,就像外婆做羊肉汤时的用心配方,既有营养又好喝。相信你也能像我一样,享受到这锅“高效美味”的代码大餐!
至此,12个优化技巧分享完了,希望大家在实际开发中能有所收获!

-END-


ok,今天先说到这,老规矩,给大家分享一份不错的副业资料,感兴趣的同学找我领取。

以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言

程序员老鬼
10年+老程序员,专注于AI知识普及,已打造多门AI课程,本号主要分享国内AI工具、AI绘画提示词、Chat教程、AI换脸、Chat中文指令、Sora教程等,帮助读者解决AI工具使用疑难问题。
 最新文章