MyBatis‑Plus Service 层常用自带方法
前提:你的
UserServiceImpl继承了ServiceImpl<UserMapper, User>所以所有这些方法,在你的service实现类里面可以直接调用,不用写 mapper、不用写sql。
java
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
"这里就能直接用 query()、save()、updateById() ..."
}
两套API区分清楚:
1️⃣ Service链式(LambdaQuery / query()) :
query().eq().one()2️⃣ Service普通方法 :
save、saveBatch、updateById、removeById、getById3️⃣ Mapper层方法:
userMapper.selectById()(不推荐在service优先使用)
一、查询类(最常用)
1. query() 链式条件查询【黑马点评在用】
query() 返回一个查询构造器,支持链式拼接条件
one() 查询一条
java
// where phone = 13800138000
User user = query()
.eq("phone", "13800138000")
.one();
- 查到1条 → 返回对象
- 查到0条 → null
- 查到≥2条 → 抛异常
list() 查询多条,返回集合
java
// 查询状态为正常的所有用户
List<User> userList = query()
.eq("status", 1)
.list();
count() 统计条数
java
// 查询手机号是否已经存在
long count = query()
.eq("phone", "13800138000")
.count();
if(count > 0){
//手机号已注册
}
getOne(Wrapper) 老版写法(不推荐链式以外的)
现在优先用 query()
lambdaQuery() 👉【生产环境强烈推荐!!】
query() 写字符串字段名 "phone",拼写错不会编译报错!
lambdaQuery() 用实体属性,编译校验,不会写错
java
User user = lambdaQuery()
.eq(User::getPhone, "13800138000")
.one();
List<User> list = lambdaQuery()
.eq(User::getStatus,1)
.list();
✅ 企业开发优先 lambdaQuery(),少用 query()
条件方法对照表(链式里面 .之后调用)
| 方法 | 含义 | 生成SQL |
|---|---|---|
.eq("字段",值) |
等于 | phone = ? |
.ne("字段",值) |
不等于 | phone <> ? |
.gt("age",18) |
大于 | age > 18 |
.ge("age",18) |
大于等于 | age >=18 |
.lt("age",18) |
小于 | age < 18 |
.le("age",18) |
小于等于 | age <= 18 |
.like("name","张") |
模糊查询 %张% | name like '%张%' |
.likeLeft("name","三") |
%三 | name like '%三' |
.likeRight("name","张") |
张% | name like '张%' |
.in("id", 1,2,3) |
id在集合里面 | id in (1,2,3) |
.isNull("email") |
字段为null | email is null |
.isNotNull("email") |
不为null | email is not null |
.orderByDesc("id") |
id降序 | order by id desc |
.orderByAsc("id") |
id升序 | order by id asc |
示例,多条件组合:
java
List<User> list = lambdaQuery()
.eq(User::getStatus, 1)
.like(User::getNickName,"张")
.ge(User::getAge, 18)
.orderByDesc(User::getId)
.list();
2. getById(id) 根据主键id查询(超级高频)
java
// 根据主键id查用户
User user = getById(1L);
- 查到返回对象,查不到返回null
3. listByIds() 根据多个id批量查询
java
List<Long> idList = Arrays.asList(1L,2L,3L);
List<User> userList = listByIds(idList);
4. list() 不带条件 → 查询整张表全部数据
⚠️ 数据量大禁止使用!!
java
List<User> all = list();
二、新增类
1. save(entity) 单条新增
java
User user = new User();
user.setPhone("13800138000");
user.setNickName("user_abc");
//插入一条数据
boolean success = save(user);
- 返回 boolean,true插入成功
- 主键如果是自增,插入成功后,user对象里面id会自动回填!
2. saveBatch() 批量新增(一次插入多条)
java
List<User> addList = new ArrayList<>();
addList.add(new User());
addList.add(new User());
//批量插入
boolean ok = saveBatch(addList);
三、修改更新类
1. updateById(entity) 根据主键id更新(最常用)
只更新
实体中非null的字段!!!大坑重点
java
User user = new User();
user.setId(1L);
user.setNickName("新名字");
// 根据id更新昵称
boolean ok = updateById(user);
生成SQL:update user set nick_name=? where id=?
不会把其他字段置空!只更新你设置过的属性
2. update(实体, 更新条件Wrapper) 条件更新
MP 只会更新实体中你 set 过、不为 null 的字段 。
你只 setNickName,所以只会更新 nick_name,其他字段完全不动,不会被清空。
按条件更新,不是根据主键
java
// 把所有 status=0 的用户,昵称改成游客
User updateEntity = new User();
updateEntity.setNickName("游客");
boolean ok = update(
updateEntity,
lambdaUpdate()
.eq(User::getStatus,0)
);
lambdaUpdate() 链式构建更新条件
四、删除类
1. removeById(id) 根据主键删除
java
boolean ok = removeById(1L);
2. remove(条件Wrapper) 按条件删除
java
//删除手机号为空的用户
boolean ok = remove(
lambdaQuery()
.isNull(User::getPhone)
);
3. removeByIds() 批量删除多个id
java
List<Long> ids = Arrays.asList(1L,2L);
boolean ok = removeByIds(ids);
⚠️实际业务几乎不做物理删除 !用逻辑删除,加字段
is_deleted
五、分页查询 - 高频
java
"pageNum当前页,pageSize每页条数"
Page<User> page = new Page<>(1,5);
// 分页查询,状态为1的用户
Page<User> resultPage = page(page,
lambdaQuery()
.eq(User::getStatus, 1)
);
// 获取分页数据
List<User> records = resultPage.getRecords();
// 总条数
long total = resultPage.getTotal();
⚠️分页功能必须配置MyBatis‑Plus分页拦截器,否则分页失效!
六、一张速查表:Service层高频方法
| 方法 | 作用 |
|---|---|
getById(id) |
主键id查单条 |
save(entity) |
新增一条 |
updateById(entity) |
根据主键更新 |
removeById(id) |
主键删除 |
query().eq().one() |
条件查一条(字符串字段) |
lambdaQuery().eq().one() |
条件查一条【推荐】 |
lambdaQuery().eq().list() |
条件查列表 |
lambdaQuery().count() |
条件统计数量 |
lambdaUpdate() |
链式条件更新 |
page(page,wrapper) |
分页查询 |
七、容易踩的4个坑(高频出错)
坑1:updateById 只更新非null字段
如果你写:
java
User user = new User();
user.setId(1L);
// 没有设置nickName
updateById(user);
只会更新id,其他字段不动,不会清空。
坑2:one() 查到多条抛异常
如果你用手机号查询,数据库如果不小心存了两条相同手机号,one()直接崩溃。
坑3:query("phone")字符串写错,运行时报错,编译不报红
👉解决:生产一律优先 lambdaQuery(User::getPhone)
坑4:MP的save不会自动给你填创建时间、更新时间
需要自动填充(createTime、updateTime),要用MetaObjectHandler