目录
[4.3.5 获取BaseMapper和实体类](#4.3.5 获取BaseMapper和实体类)
[4.3.6 链式查询](#4.3.6 链式查询)
[4.3.7 链式更改](#4.3.7 链式更改)
4.3.5 获取BaseMapper和实体类
-
获取BaseMapper
getBaseMapper() 用于获取当前 Service 对应的 BaseMapper 接口实例,可直接调用 Mapper 层的原生方法(如 insert、deleteById、selectList 等)。/**
- 获取对应 entity 的 BaseMapper
- @return BaseMapper
*/
BaseMapper<T> getBaseMapper();
@Test
public void getBaseMapper(){
BaseMapper<User> baseMapper = userService.getBaseMapper();
System.out.println("getBaseMapper() 返回值:" + baseMapper);
System.out.println("getBaseMapper() 返回值类型:" + baseMapper.getClass().getName());
}

-
获取实体类
/**
- 获取 entity 的 class
- @return {@link Class<T>}
*/
Class<T> getEntityClass();
@Test
public void getEntityClass(){
Class<User> entityClass = userService.getEntityClass();
System.out.println("getEntityClass() 返回值:" + entityClass);
System.out.println("实体类全限定名:" + entityClass.getName());
System.out.println("实体类简单类名:" + entityClass.getSimpleName());
}

4.3.6 链式查询
"链式" 本质就是方法调用可以像链条一样连起来写------ 一个方法执行完后,返回当前对象(或同类对象),然后直接用这个返回值接着调用下一个方法,不用每次都重新获取对象、单独写一行。
示例:
- 非链式写法(传统方式)
要查询 "name = 张三且 age>20" 的用户,得分步写:
// 第一步:创建查询条件对象
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 第二步:设置第一个条件
queryWrapper.eq("name", "张三");
// 第三步:设置第二个条件
queryWrapper.gt("age", 20);
// 第四步:执行查询
User user = userService.getOne(queryWrapper);
每一步都要操作 queryWrapper 对象,代码是 "断的",需要重复写对象名。
- 链式写法(MyBatis-Plus 的链式方法)
用 query() 链式查询,代码是 "连的":
User user = userService.query() // 第一步:获取链式查询对象
.eq("name", "张三") // 第二步:设置条件,返回自身
.gt("age", 20) // 第三步:继续设置条件,返回自身
.one(); // 第四步:执行查询,得到结果
-
query() 返回 QueryChainWrapper 对象;
-
.eq(...) 执行后,还是返回这个 QueryChainWrapper 对象;
-
所以可以接着调 .gt(...),再接着调 .one(),像链条一样串起来。
核心原理:
链式方法的关键是:每个方法执行完后,返回当前对象(return this;)或同类对象。比如 QueryChainWrapper 的 eq() 方法内部大概是这样的:public QueryChainWrapper<T> eq(String column, Object value) {
this.queryWrapper.eq(column, value); // 设置条件
return this; // 返回自己,才能继续链式调用
}
下面的方法用于构建查询条件,最终调用 one()/list() 等执行查询。
-
普通链式查询
/**
- 链式查询 普通
- @return QueryWrapper 的包装类
*/
default QueryChainWrapper<T> query() {
return ChainWrappers.queryChain(getBaseMapper());
}
链式查询(普通),返回 QueryChainWrapper 对象,支持通过字符串指定字段名构建查询条件,最终调用 one()、list() 等方法执行查询。
@Test
public void query(){
// 查询name为"张三"且age>20的第一条用户
User user = userService.query()
.eq("name", "张三")
.gt("age", 0)
// .last("LIMIT 1") // 只取第一条
// .one(); // 执行查询并返回单条结果,要<=1条,不然会报错
.list()
.get(0);//前提是查询出来的List<User不能为空,不然会报错,或者是下面重新判断在get
System.out.println("查询结果:" + user);
// 查询所有status为1的用户列表
List<User> userList = userService.query()
.eq("name", "张三")
.orderByDesc("id")
.list(); // 执行查询并返回列表
System.out.println("用户列表:" + userList);
}


-
lambda 式链式查询
/**
- 链式查询 lambda 式
-
注意:不支持 Kotlin
- @return LambdaQueryWrapper 的包装类
*/
default LambdaQueryChainWrapper<T> lambdaQuery() {
return ChainWrappers.lambdaQueryChain(getBaseMapper());
}
链式查询(Lambda 式),返回 LambdaQueryChainWrapper 对象,支持通过实体类方法引用(User::getName)指定字段,避免字符串硬编码,更安全。不支持 Kotlin。
@Test
public void lambdaQuery(){
// 查询age<=30且email不为空的用户列表
List<User> userList = userService.lambdaQuery()
.le(User::getAge, 30)
.isNotNull(User::getEmail)
.list();
System.out.println("Lambda查询结果:" + userList);
// 查询id为1的用户
User user = userService.lambdaQuery()
.eq(User::getId, 1L)
.one();
System.out.println("Lambda单条查询:" + user);
}


-
kotlin 使用的lambda 式链式查询
Kotlin 是基于 Java 生态 设计的一种静态类型的编程语言。Kotlin 完全兼容 Java(兼容指定是类和方法能互相调用,比如 Kotlin 类能调用 Java 类,Java 类也能调用 Kotlin 类)),但语法更简洁、功能更丰富(比如空安全、数据类、扩展函数等)。
简单说:Kotlin 是 Java 的 "升级版",但它们都是独立的编程语言。
ktQuery() 是给 Kotlin 用的,Java 用 lambdaQuery() 就行(功能一样,语法适配 Java)。/**
- 链式查询 lambda 式
- kotlin 使用
- @return KtQueryWrapper 的包装类
*/
default KtQueryChainWrapper<T> ktQuery() {
return ChainWrappers.ktQueryChain(getBaseMapper(), getEntityClass());
}
4.3.7 链式更改
用于构建更新 / 删除条件,最终调用 update()/remove() 执行操作。
-
kotlin 使用的lambda 式链式更改
default KtUpdateChainWrapper<T> ktUpdate() {
return ChainWrappers.ktUpdateChain(getBaseMapper(), getEntityClass());
} -
普通链式更改
/**
- 链式更改 普通
- @return UpdateWrapper 的包装类
*/
default UpdateChainWrapper<T> update() {
return ChainWrappers.updateChain(getBaseMapper());
}
链式更改(普通),返回 UpdateChainWrapper 对象,通过字符串指定字段名构建更新条件和修改内容,最终调用 update()、remove() 等方法执行操作。
@Test
public void update2(){
// 将age>30的用户status改为0
boolean updateSuccess = userService.update()
.gt("age", 99)
.set("age", 101)
.update(); // 执行更新操作
System.out.println("更新是否成功:" + updateSuccess);
// 删除email为null的用户
boolean deleteSuccess = userService.update()
.isNull("email")
.remove(); // 执行删除操作
System.out.println("删除是否成功:" + deleteSuccess);
}

-
lambda 式链式更改
/**
- 链式更改 lambda 式
-
注意:不支持 Kotlin
- @return LambdaUpdateWrapper 的包装类
*/
default LambdaUpdateChainWrapper<T> lambdaUpdate() {
return ChainWrappers.lambdaUpdateChain(getBaseMapper());
}
链式更改(Lambda 式),返回 LambdaUpdateChainWrapper 对象,通过实体类方法引用指定字段,避免字符串硬编码,不支持 Kotlin。
@Test
public void lambdaUpdate(){
// 将id为101的用户name改为"李四",email改为"lisi@example.com"
boolean success = userService.lambdaUpdate()
.eq(User::getId, 101L)
.set(User::getName, "李四")
.set(User::getEmail, "lisi@example.com")
.update();
System.out.println("Lambda更新是否成功:" + success);
// 删除age<1的用户
boolean deleteSuccess = userService.lambdaUpdate()
.lt(User::getAge, 1)
.remove();
System.out.println("Lambda删除是否成功:" + deleteSuccess);
}

-
更新修改
/**
-
- 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
- 此次修改主要是减少了此项业务代码的代码量(存在性验证之后的saveOrUpdate操作)
- @param entity 实体对象
*/
default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
return update(entity, updateWrapper) || saveOrUpdate(entity);
}
-
先尝试根据 updateWrapper 条件更新 entity 中的数据;若更新失败(无匹配记录),则执行 saveOrUpdate(entity)(根据主键判断:有主键则更新,无则新增)。
@Test
public void saveOrUpdate1(){
// 构造实体对象(假设id为101的用户存在,否则新增)
User user = new User();
user.setId(101L);
user.setName("新名称");
user.setAge(28);
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq("name", "旧名称");
// 尝试根据name="旧名称"的条件更新,失败则执行saveOrUpdate
boolean result = userService.saveOrUpdate(user, queryWrapper);
System.out.println("saveOrUpdate结果:" + result);
}
