[特殊字符] MyBatis-Plus:我 CRUD 都不用手写了?老板直呼“这班上的太轻松了”!
副标题:从“写 SQL 写到头秃”到“一行代码查全表”,MyBatis-Plus 让我提前进入退休生活(不是)
大家好,我是 Qcby,一个曾经每天和 SELECT * FROM user WHERE id = ? 斗智斗勇的 Java 程序员。
直到有一天,我遇到了 MyBatis-Plus(简称 MP) —— 这哪是框架?这分明是我的“摸鱼外挂”!
今天就带大家看看,如何用 MP 把 CRUD 变成“复制粘贴”,顺便把分页、乐观锁、逻辑删除、枚举统统安排得明明白白!
🚀 1. 起飞前准备:加个依赖,扫个包
首先,Maven 里加个“魔法粉”:
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
然后在启动类上贴个“召唤符”:
java
@MapperScan("com.qcby.mybatisplusdemo.mapper")
搞定!MP 已经在后台默默为你打工了。
👤 2. 实体类:注解一加,字段自动对齐!
以前写实体类,总要担心:
“数据库字段是
user_name,我 Java 属性写userName,会不会查不到?”
“主键是不是自增?要不要手动设 ID?”
“删用户真的要物理删?不怕老板半夜打电话?”
现在?注解安排!
java
@Data
public class User {
@TableId(type = IdType.AUTO)
private Long id;
@TableField("username") // 数据库叫 username,我偏要叫 name!
private String name;
private Integer age;
private String email;
private SexEnum sex; // 枚举?小菜一碟!
@TableLogic // 逻辑删除:删了但没完全删
private Integer isDeleted;
@TableField(exist = false) // 这个字段只存在于我的幻想中(比如确认密码)
private String confirmPassword;
}
看懂了吗?
@TableId:主键策略,AUTO 表示“数据库你看着办”。@TableField("xxx"):字段名不一致?我来桥接!@TableLogic:删除?不存在的!只是把isDeleted改成 1 而已~exist = false:这个字段纯属“精神寄托”,数据库里根本没有!
💡 小知识:MP 默认开启 驼峰转下划线,所以
createTime→create_time自动映射,根本不用写注解!
🔌 3. 插件全家桶:分页 + 乐观锁,一键启用!
在 MybatisPlusConfig.java 里,我们装两个“外挂”:
java
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件:查第几页?每页几条?MP 帮你算!
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁:防止小王和小李同时改商品价格,结果价格变成负数(别问,问就是血泪史)
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
从此以后:
userService.page(new Page<>(1, 5))→ 直接返回分页数据!- 给
Product加个@Version字段 → 更新时自动校验版本号,冲突直接失败!
java
public class Product {
private Long id;
private String name;
private Integer price;
@Version // 乐观锁核心!每次更新 version+1
private Integer version;
}
🧪 测试结果:小王更新失败后重试,最终价格 120,老板满意,世界和平 ✌️
🧙 4. Mapper & Service:继承即战力!
Mapper 只需继承 BaseMapper<User>:
java
public interface UserMapper extends BaseMapper<User> {}
Service 更狠:
java
public interface UserService extends IService<User> {}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
然后你就能在 Controller 里疯狂调用:
java
@GetMapping("/list")
public List<User> list() {
return userService.list(); // 查所有!
}
@PostMapping("/add")
public boolean add(@RequestBody User user) {
return userService.save(user); // 新增!
}
@DeleteMapping("/delete/{id}")
public boolean delete(@PathVariable Long id) {
return userService.removeById(id); // 逻辑删除!
}
@GetMapping("/page")
public Page<User> page(int pageNum, int pageSize) {
return userService.page(new Page<>(pageNum, pageSize)); // 分页!
}
连 SQL 都不用写!
老板:“你这功能怎么这么快?”
我:“因为我站在巨人的肩膀上……而且巨人还帮我写了 CRUD。”
🎯 5. 条件查询?LambdaQueryWrapper 来了!
想查“名字带‘a’且年龄大于10”的用户?
java
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "a")
.ge(User::getAge, 10);
return userService.list(wrapper);
注意!这里用的是 User::getName,不是字符串 "name"!
再也不怕手滑写错字段名导致半夜报警了!
🧪 6. 测试?MP 连测试都给你想好了!
java
@Test
void testOptimisticLock() {
// 小李读价格 → 100
// 小王读价格 → 100
// 小李 +50 → 成功,version=1
// 小王 -30 → 失败!因为 version 还是 0
// 小王重试 → 成功!
// 最终价格:120
}
这不比写文档清楚?
💬 结语:MP 不是偷懒,是高效!
MyBatis-Plus 并不是让你“不写代码”,而是把重复劳动交给框架,把创造力留给自己。
- 基础 CRUD?MP 给你。
- 分页?MP 给你。
- 逻辑删除?MP 给你。
- 乐观锁?MP 给你。
- 枚举映射?MP 给你。
你只需要专注业务逻辑,比如:
“用户注册时要不要发短信?”
“商品打折能不能叠加优惠券?”
而不是纠结:
“我的 XML 写错没?”
“分页的 limit offset 对不对?”
🎉 最后送大家一句话:
“优秀的程序员,不是写最多的代码,而是让代码写得最少。”
—— 某个用了 MyBatis-Plus 后每天准时下班的人
项目源码已开源(假装),欢迎点赞、收藏、转发三连!
下次我们聊聊 MP + 多数据源 + 动态表名,让你的系统“灵活到飞起”!
👋 我是 周星星,一个正在努力不被 CRUD 压垮的程序员。
关注我,带你用最骚的姿势,写出最稳的代码!
更多推荐



所有评论(0)