文章目录
-
- 基于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 内部对象注入容器,内部包含常见的单表操作
总结
- 条件构建 :优先使用
LambdaQueryWrapper替代QueryWrapper,避免硬编码数据库列名导致错误。 - 关键注意点 :
selectOne:条件匹配多条记录会抛异常,仅用于"唯一条件"场景;selectByMap:Map 的 key 是数据库列名(不是实体属性名);selectPage:必须先配置分页插件,否则分页失效(只会查所有数据);
- 空值处理 :
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)