mybatis-plus 基于 Mapper接口的 select

文章目录

    • 基于BaseMapper的crud
    • 前置准备(必看)
    • [各方法使用示例(在 UserService 中编写)](#各方法使用示例(在 UserService 中编写))
      • [1. selectById:根据 ID 查询单个实体](#1. selectById:根据 ID 查询单个实体)
      • [2. selectOne:根据条件查询单个记录](#2. selectOne:根据条件查询单个记录)
      • [3. selectBatchIds:批量根据 ID 查询](#3. selectBatchIds:批量根据 ID 查询)
      • [4. selectList:根据条件查询全部记录](#4. selectList:根据条件查询全部记录)
      • [5. selectByMap:根据 Map 条件查询](#5. selectByMap:根据 Map 条件查询)
      • [6. selectMaps:查询结果转 Map 列表](#6. selectMaps:查询结果转 Map 列表)
      • [7. selectObjs:只返回第一个字段的值](#7. selectObjs:只返回第一个字段的值)
      • [8. selectPage:分页查询(需先配置分页插件)](#8. selectPage:分页查询(需先配置分页插件))
      • [9. selectMapsPage:分页查询结果转 Map](#9. selectMapsPage:分页查询结果转 Map)
      • [10. selectCount:查询符合条件的总记录数](#10. selectCount:查询符合条件的总记录数)

基于BaseMapper的crud

  • 通用 CRUD 封装 BaseMapper接口,
  • Mybatis-Plus 启动时,自动解析实体表关系映射转换为 Mybatis 内部对象注入容器,内部包含常见的单表操作

总结

  1. 条件构建 :优先使用 LambdaQueryWrapper 替代 QueryWrapper,避免硬编码数据库列名导致错误。
  2. 关键注意点 :
    • selectOne:条件匹配多条记录会抛异常,仅用于"唯一条件"场景;
    • selectByMap:Map 的 key 是数据库列名(不是实体属性名);
    • selectPage:必须先配置分页插件,否则分页失效(只会查所有数据);
  3. 空值处理 :selectList/selectMaps 无匹配结果时返回空 List(不是 null),无需额外判空。


前置准备(必看)

先定义通用的实体类、Mapper 接口和注入方式,后续示例都基于此:

java 复制代码
// 1. 实体类(对应数据库 user 表)
@Data
@TableName("user") // 指定数据库表名
public class User {
    @TableId(type = IdType.AUTO) // 主键自增
    private Long id;          // 数据库字段:id (BIGINT)
    private String userName;  // 数据库字段:user_name (VARCHAR)
    private Integer age;      // 数据库字段:age (INT)
    private String email;     // 数据库字段:email (VARCHAR)
}

// 2. Mapper 接口(继承 BaseMapper)
public interface UserMapper extends BaseMapper<User> {
}

// 3. Spring Boot 环境下注入 Mapper(Service 层示例)
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper; // 注入 Mapper,后续示例都用这个对象
}

各方法使用示例(在 UserService 中编写)

1. selectById:根据 ID 查询单个实体

java 复制代码
// 根据 ID=1 查询用户
public User getUserById(Long id) {
    // 参数:主键 ID(支持 Integer/Long/String 等 Serializable 类型)
    User user = userMapper.selectById(1L);
    return user;
}
// 输出示例:User(id=1, userName="张三", age=20, email="zhangsan@test.com")

2. selectOne:根据条件查询单个记录

注意:如果匹配结果超过 1 条,会抛出 TooManyResultsException 异常,适合确定条件唯一的场景。

java 复制代码
// 根据用户名查询单个用户(假设 userName 唯一)
public User getUserByUserName(String userName) {
    // 构建查询条件:eq = equals(等于)
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .eq("user_name", userName); // 这里填数据库列名,或用 lambda 避免硬编码
    
    // Lambda 写法(推荐,避免列名写错):
    // LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<User>()
    //        .eq(User::getUserName, userName);
    
    User user = userMapper.selectOne(queryWrapper);
    return user;
}
// 输入:userName="张三" → 输出:唯一匹配的 User 对象(无结果返回 null)

3. selectBatchIds:批量根据 ID 查询

java 复制代码
// 批量查询 ID=1、2、3 的用户
public List<User> listUserByIds() {
    // 参数:ID 集合(List/Set 等 Collection 类型)
    List<Long> idList = Arrays.asList(1L, 2L, 3L);
    List<User> userList = userMapper.selectBatchIds(idList);
    return userList;
}
// 输出:包含 3 个 User 对象的 List(无匹配 ID 则对应位置无数据)

4. selectList:根据条件查询全部记录

java 复制代码
// 查询年龄大于 18 且邮箱不为空的用户
public List<User> listUserByCondition() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .gt("age", 18)    // gt = greater than(大于)
            .isNotNull("email"); // 邮箱不为空
    
    List<User> userList = userMapper.selectList(queryWrapper);
    return userList;
}
// 输出:所有符合条件的 User 对象列表(无结果返回空 List,不会为 null)

5. selectByMap:根据 Map 条件查询

关键:Map 的 key 是数据库列名(不是实体属性名),value 是匹配值,条件默认是"等于"。

java 复制代码
// 查询 age=20 且 user_name="张三" 的用户
public List<User> listUserByMap() {
    Map<String, Object> columnMap = new HashMap<>();
    columnMap.put("age", 20);          // 数据库列名:age
    columnMap.put("user_name", "张三");// 数据库列名:user_name(不是 userName)
    
    List<User> userList = userMapper.selectByMap(columnMap);
    return userList;
}
// 输出:符合条件的 User 列表(多条件默认 AND 关系)

6. selectMaps:查询结果转 Map 列表

适合不需要实体类、只需要部分字段的场景,Map 的 key 是数据库列名,value 是字段值。

java 复制代码
// 查询年龄>18的用户的 id 和 user_name
public List<Map<String, Object>> listUserMap() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .select("id", "user_name") // 只查询指定列(减少数据传输)
            .gt("age", 18);
    
    List<Map<String, Object>> mapList = userMapper.selectMaps(queryWrapper);
    return mapList;
}
// 输出示例:[{id=1, user_name=张三}, {id=2, user_name=李四}]

7. selectObjs:只返回第一个字段的值

不管查询的是哪些列,只取结果集中第一列的值,适合只需要主键 ID 列表的场景。

java 复制代码
// 查询所有年龄>18的用户的 ID(只取第一列)
public List<Object> listUserId() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .select("id") // 显式指定第一列为 id(推荐)
            .gt("age", 18);
    
    List<Object> idList = userMapper.selectObjs(queryWrapper);
    return idList;
}
// 输出示例:[1, 2, 3](Long 类型的 ID 被封装为 Object)

8. selectPage:分页查询(需先配置分页插件)

第一步:先配置 MyBatis-Plus 分页插件(Spring Boot 配置类):

java 复制代码
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分页插件(适配 MySQL)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

第二步:分页查询示例:

java 复制代码
// 分页查询:第 1 页,每页 10 条,条件:age>18
public IPage<User> pageUser(int pageNum, int pageSize) {
    // 1. 构建分页对象(页码从 1 开始,不是 0)
    IPage<User> page = new Page<>(pageNum, pageSize);
    
    // 2. 构建查询条件
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .gt("age", 18);
    
    // 3. 分页查询(结果会自动封装到 page 对象中)
    IPage<User> userPage = userMapper.selectPage(page, queryWrapper);
    
    // 分页结果常用属性
    long total = userPage.getTotal(); // 总记录数
    long pages = userPage.getPages(); // 总页数
    List<User> records = userPage.getRecords(); // 当前页数据列表
    
    return userPage;
}
// 调用:pageUser(1, 10) → 输出第 1 页的 10 条数据,及总记录数/总页数

9. selectMapsPage:分页查询结果转 Map

用法和 selectPage 一致,只是返回结果是 Map 列表(适合不需要实体类的场景):

java 复制代码
// 分页查询:第 1 页,每页 10 条,只查 id 和 user_name
public IPage<Map<String, Object>> pageUserMap(int pageNum, int pageSize) {
    IPage<Map<String, Object>> page = new Page<>(pageNum, pageSize);
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .select("id", "user_name")
            .gt("age", 18);
    
    IPage<Map<String, Object>> mapPage = userMapper.selectMapsPage(page, queryWrapper);
    return mapPage;
}
// 输出:分页对象中 records 是 Map 列表,包含 id 和 user_name 字段

10. selectCount:查询符合条件的总记录数

java 复制代码
// 查询年龄>18的用户总数
public Integer countUserByAge() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
            .gt("age", 18);
    
    Integer count = userMapper.selectCount(queryWrapper);
    return count;
}
// 输出:符合条件的记录数(比如 50)
相关推荐
xcl09251 天前
北京24小时自助健身房系统软件开发实战:从架构到部署全流程指南
java·spring boot·架构
一 乐1 天前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长1 天前
w214基于jsp知道特产网
java·intellij-idea
步行cgn1 天前
Spring 注解使用详解
java·spring
一条小小yu1 天前
Spring IoC的理解
java·后端·spring
落魄实习生1 天前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈1 天前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白1 天前
核心功能(Service接口)
java·mybatis
乌暮1 天前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习