IService——查询(下)

目录

[4.3.5 获取BaseMapper和实体类](#4.3.5 获取BaseMapper和实体类)

[4.3.6 链式查询](#4.3.6 链式查询)

[4.3.7 链式更改](#4.3.7 链式更改)


4.3.5 获取BaseMapper和实体类

  1. 获取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());
    }

  1. 获取实体类

    /**

    • 获取 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 链式查询

"链式" 本质就是方法调用可以像链条一样连起来写------ 一个方法执行完后,返回当前对象(或同类对象),然后直接用这个返回值接着调用下一个方法,不用每次都重新获取对象、单独写一行。

示例:

  1. 非链式写法(传统方式)

要查询 "name = 张三且 age>20" 的用户,得分步写:

复制代码
// 第一步:创建查询条件对象
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
// 第二步:设置第一个条件
queryWrapper.eq("name", "张三");
// 第三步:设置第二个条件
queryWrapper.gt("age", 20);
// 第四步:执行查询
User user = userService.getOne(queryWrapper);

每一步都要操作 queryWrapper 对象,代码是 "断的",需要重复写对象名。

  1. 链式写法(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() 等执行查询。

  1. 普通链式查询

    /**

    • 链式查询 普通
    • @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);
    }


  1. 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);
}
  1. 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() 执行操作。

  1. kotlin 使用的lambda 式链式更改

    default KtUpdateChainWrapper<T> ktUpdate() {
    return ChainWrappers.ktUpdateChain(getBaseMapper(), getEntityClass());
    }

  2. 普通链式更改

    /**

    • 链式更改 普通
    • @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);
}
  1. 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);
}
  1. 更新修改

    /**

    • 根据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);
}
相关推荐
磊 子2 小时前
mysql数据库2
数据库
众创岛2 小时前
python中enumerate的用法
开发语言·python
add45a2 小时前
C++中的智能指针详解
开发语言·c++·算法
在荒野的梦想2 小时前
Java 调用 OpenAI / Claude API 完整实战指南
java
ulias2122 小时前
函数栈帧的创建和销毁
开发语言·数据结构·c++·windows·算法
2301_818419012 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
代码探秘者2 小时前
【算法篇】3.位运算
java·数据结构·后端·python·算法·spring
jinanwuhuaguo2 小时前
OpenClaw v2026.3.23 深度技术分析报告:平台地基的加固与成熟度宣言
运维·数据库·人工智能·openclaw
李白的粉2 小时前
基于springboot的新闻稿件管理系统
java·spring boot·毕业设计·课程设计·源代码·新闻稿件管理系统