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)
相关推荐
青云计划8 小时前
知光项目知文发布模块
java·后端·spring·mybatis
赶路人儿8 小时前
Jsoniter(java版本)使用介绍
java·开发语言
探路者继续奋斗9 小时前
IDD意图驱动开发之意图规格说明书
java·规格说明书·开发规范·意图驱动开发·idd
消失的旧时光-19439 小时前
第十九课:为什么要引入消息队列?——异步系统设计思想
java·开发语言
A懿轩A10 小时前
【Java 基础编程】Java 面向对象入门:类与对象、构造器、this 关键字,小白也能写 OOP
java·开发语言
乐观勇敢坚强的老彭10 小时前
c++寒假营day03
java·开发语言·c++
biubiubiu070610 小时前
谷歌浏览器无法访问localhost:8080
java
大黄说说11 小时前
新手选语言不再纠结:Java、Python、Go、JavaScript 四大热门语言全景对比与学习路线建议
java·python·golang
烟沙九洲11 小时前
Java 中的 封装、继承、多态
java
识君啊11 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端