BaseMapper 增删改查
# BaseMapper 增删改查
前言
BaseMapper<T>
是 MyBatis-Plus 提供的通用 Mapper 接口,封装了常见的增删改查操作。通过继承这个接口,开发者可以直接使用 MyBatis-Plus 提供的基础 CRUD 功能,无需手动编写 SQL 语句。
# 1. BaseMapper<T>
的核心特点
- 通用性:
BaseMapper<T>
是一个通用接口,适用于任意实体对象,只需要指定泛型T
即可。 - 自动解析:MyBatis-Plus 在启动时会自动解析实体表关系映射,并将其转换为 MyBatis 内部对象,注入到 Spring 容器中。
- 简化开发:开发者只需继承
BaseMapper<T>
,即可使用内置的 CRUD 方法,大幅减少了样板代码的编写。
# 2. BaseMapper<T>
中提供的 CRUD 方法
# 2.1 增加:insert
// 插入一条记录
int insert(T entity);
2
- 功能:将实体对象插入数据库。
- 参数:
T entity
- 要插入的实体对象。 - 返回值:返回插入操作影响的行数。一般情况下,返回值为 1 表示插入成功。
# 2.2 删除:delete
// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据 ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
2
3
4
5
6
7
8
9
10
11
- 功能:提供多种删除方式,支持根据条件、ID、Map 等进行删除操作。
- 参数:
Wrapper<T> wrapper
- 条件构造器,用于指定删除条件。Collection<? extends Serializable> idList
- 批量删除时传入的 ID 集合。Serializable id
- 单个 ID,指定要删除的记录。Map<String, Object> columnMap
- 根据 Map 中的条件删除匹配的数据。
- 返回值:返回删除操作影响的行数。
# 2.3 修改:update
// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
2
3
4
5
- 功能:提供根据条件或根据 ID 进行更新操作。
- 参数:
T updateEntity
- 要更新的实体对象。Wrapper<T> whereWrapper
- 条件构造器,用于指定更新条件。T entity
- 根据 ID 更新时使用的实体对象。
- 返回值:返回更新操作影响的行数。
# 2.4 查询:select
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意:只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 功能:提供多种查询方式,支持根据 ID、条件、Map、分页等进行查询操作。
- 参数:
Serializable id
- 指定查询的 ID。Wrapper<T> queryWrapper
- 条件构造器,用于指定查询条件。Collection<? extends Serializable> idList
- 批量查询时传入的 ID 集合。Map<String, Object> columnMap
- 根据 Map 中的条件查询匹配的数据。IPage<T> page
- 分页参数,指定页码和每页大小。
- 返回值:返回匹配的实体对象或结果列表,具体返回类型取决于查询方法。
# 3. 调用 BaseMapper<T>
操作数据库步骤
# 3.1 定义实体类
首先需要定义一个与数据库表对应的实体类。通常,我们会使用 MyBatis-Plus 提供的注解来与数据库表进行映射:
@Data // Lombok 注解,自动生成 getter/setter 方法
@TableName("user") // 与数据库表 "user" 进行映射
public class User {
private Long id; // 主键 ID
private String name; // 用户名
private Integer age; // 年龄
private String email; // 邮箱
}
2
3
4
5
6
7
8
说明:
@TableName
注解用于指定实体类与数据库表的映射关系。@Data
注解是 Lombok 提供的,自动生成常见的 getter/setter 等方法,简化代码编写。
# 3.2 定义 Mapper 接口
在 MyBatis-Plus 中,Mapper 接口是直接继承 BaseMapper<T>
的。通过继承 BaseMapper<T>
,可以直接使用 MyBatis-Plus 提供的 CRUD 方法:
@Mapper // MyBatis 注解,标识这是一个 Mapper 接口
public interface UserMapper extends BaseMapper<User> {
// 这里可以自定义一些查询方法
}
2
3
4
说明:
UserMapper
是数据访问层的接口,它继承了BaseMapper<User>
,因此可以直接使用 CRUD 方法。- 如果需要自定义 SQL 查询方法,可以在这里声明并在对应的 XML 文件中实现。
# 3.3 在 Service 层调用 BaseMapper<T>
方法
在 Service 层,我们通过注入 UserMapper
来调用 CRUD 方法。UserMapper
是数据访问层的接口,负责与数据库交互:
@Service // 标识这是一个服务层的组件
public class UserService {
@Autowired // 自动注入 UserMapper
private UserMapper userMapper;
/**
* 根据 ID 查询用户
* @param id 用户 ID
* @return 查询到的用户对象
*/
public User getUserById(Long id) {
return userMapper.selectById(id); // 调用 BaseMapper 提供的 selectById 方法查询数据
}
/**
* 保存用户信息
* @param user 要保存的用户对象
* @return 保存结果,true 表示成功
*/
public boolean saveUser(User user) {
return userMapper.insert(user) > 0; // 调用 BaseMapper 的 insert 方法保存数据,返回受影响的行数
}
/**
* 查询所有用户
* @return 用户列表
*/
public List<User> getAllUsers() {
return userMapper.selectList(null); // 调用 BaseMapper 的 selectList 方法查询所有数据
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
说明:
selectById
是BaseMapper
提供的查询方法,传入主键 ID,返回对应的实体对象。insert
是BaseMapper
提供的插入方法,传入实体对象后将其保存到数据库中。selectList
是BaseMapper
提供的查询方法,传入查询条件(这里传null
表示查询所有),返回结果列表。
# 3.4 调用示例
在 Controller 或其他地方调用 Service 层的方法来实现业务逻辑:
@RestController // 标识这是一个控制器组件
@RequestMapping("/user") // 设置请求路径
public class UserController {
@Autowired // 自动注入 UserService
private UserService userService;
/**
* 根据 ID 获取用户
* @param id 用户 ID
* @return 查询到的用户对象
*/
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id); // 调用 Service 层的查询方法
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4. 调用 Mapper 层实现 CRUD 操作
在 MyBatis-Plus 中,通过继承 BaseMapper<T>
接口,开发者可以快速实现基础的增删改查操作。
# 4.1 插入操作
MyBatis-Plus 在实现插入数据时,会默认基于雪花算法的策略生成 ID
/**
* 插入一条数据
* MyBatis-Plus 在插入数据时默认使用雪花算法生成唯一 ID
* @return 插入操作的结果行数,通常为 1 表示成功
*/
@Test
public void testInsert(){
User user = new User();
user.setName("Vz");
user.setAge(21);
user.setEmail("vz@oz6.cn");
int result = userMapper.insert(user); // 插入数据
System.out.println(result > 0 ? "添加成功!" : "添加失败!");
System.out.println("受影响的行数为:" + result);
// 插入后可以自动获取生成的 ID
System.out.println("自动生成的 ID:" + user.getId());
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
重要 API 说明:
int insert(T entity)
:插入一条记录。- 参数:
T entity
- 需要插入的实体对象。 - 返回值: 返回影响的行数,通常为 1 表示插入成功。
- 参数:
# 4.2 删除操作
# a. 根据 ID 删除数据
/**
* 根据 ID 删除数据
* @param id 需要删除的记录的 ID
* @return 删除操作的结果行数
*/
@Test
public void testDeleteById(){
int result = userMapper.deleteById(1527206783590903810L); // 根据 ID 删除
System.out.println(result > 0 ? "删除成功!" : "删除失败!");
System.out.println("受影响的行数为:" + result);
}
2
3
4
5
6
7
8
9
10
11
# b. 根据 ID 批量删除数据
/**
* 根据 ID 批量删除数据
* @param idList 需要删除的记录的 ID 列表
* @return 删除操作的结果行数
*/
@Test
public void testDeleteBatchIds(){
List<Long> ids = Arrays.asList(6L, 7L, 8L); // 要删除的 ID 列表
int result = userMapper.deleteBatchIds(ids); // 批量删除
System.out.println(result > 0 ? "删除成功!" : "删除失败!");
System.out.println("受影响的行数为:" + result);
}
2
3
4
5
6
7
8
9
10
11
12
# c. 根据 Map 条件删除数据
/**
* 根据 Map 条件删除数据
* @param columnMap 包含删除条件的 Map
* @return 删除操作的结果行数
*/
@Test
public void testDeleteByMap(){
// 示例:根据 name 和 age 条件删除数据
Map<String, Object> map = new HashMap<>();
map.put("name", "Vz");
map.put("age", 21);
int result = userMapper.deleteByMap(map); // 根据 Map 条件删除
System.out.println(result > 0 ? "删除成功!" : "删除失败!");
System.out.println("受影响的行数为:" + result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
重要 API 说明:
int deleteById(Serializable id)
:根据 ID 删除记录。int deleteBatchIds(Collection<? extends Serializable> idList)
:根据 ID 列表批量删除记录。int deleteByMap(Map<String, Object> columnMap)
:根据 Map 条件删除记录。- 参数:
Map<String, Object> columnMap
- 条件 Map,键为列名,值为条件值。 - 返回值: 返回影响的行数。
- 参数:
# 4.3 修改操作
/**
* 根据 ID 修改用户信息
* @param entity 要更新的实体对象,必须包含 ID
* @return 更新操作的结果行数
*/
@Test
public void testUpdateById(){
User user = new User();
user.setId(6L); // 需要更新的记录 ID
user.setName("VzUpdate");
user.setAge(18);
user.setEmail("Vz@sina.com");
int result = userMapper.updateById(user); // 根据 ID 更新
System.out.println(result > 0 ? "修改成功!" : "修改失败!");
System.out.println("受影响的行数为:" + result);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
重要 API 说明:
int updateById(T entity)
:根据 ID 更新记录。- 参数:
T entity
- 需要更新的实体对象,必须包含 ID。 - 返回值: 返回影响的行数。
- 参数:
# a. 使用 updateById
方法
你可以通过 updateById
方法只更新某些已设置的字段。未设置的字段(为 null
)将不会被更新。
// 设定需要更新的字段
User user = new User();
user.setId(1L); // 指定要更新的记录ID
user.setName("new name"); // 只更新name字段
// 调用 updateById 方法
userMapper.updateById(user);
2
3
4
5
6
7
在这个示例中,user
对象中只设置了 id
和 name
字段,其他字段保持 null
。调用 updateById
后,MyBatis-Plus 会生成仅更新 name
字段的 SQL 语句。
# b. 使用 update
方法并通过 Wrapper
指定条件
如果你不想用 id
作为条件,或者想根据其他条件更新记录,可以使用 update
方法并结合 UpdateWrapper
。
// 创建 UpdateWrapper
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 1); // 指定更新条件
// 创建要更新的对象并设置需要更新的字段
User user = new User();
user.setName("new name"); // 只更新name字段
// 执行更新
userMapper.update(user, updateWrapper);
2
3
4
5
6
7
8
9
10
在这个示例中,通过 UpdateWrapper
指定更新的条件,然后仅更新 user
对象中 name
字段的内容。
重要提示
使用 MyBatis-Plus 的 updateById
或者 update
方法时,如果实体对象中的某个字段为 null
,且未启用自动填充或特殊策略,那么该字段在生成的 SQL 语句中通常不会被包含,也就是说,这个字段不会被更新。
# 4.4 查询操作
# a. 根据 ID 查询用户信息
/**
* 根据 ID 查询用户数据
* @param id 要查询的记录 ID
* @return 返回查询到的实体对象
*/
@Test
public void testSelectById(){
User user = userMapper.selectById(1L); // 根据 ID 查询
System.out.println(user);
}
2
3
4
5
6
7
8
9
10
# b. 根据多个 ID 查询多个用户信息
/**
* 根据多个 ID 查询用户数据
* @param idList 要查询的记录 ID 列表
* @return 返回查询到的实体对象列表
*/
@Test
public void testSelectBatchIds(){
List<Long> ids = Arrays.asList(1L, 2L, 3L); // 要查询的 ID 列表
List<User> users = userMapper.selectBatchIds(ids); // 批量查询
users.forEach(System.out::println);
}
2
3
4
5
6
7
8
9
10
11
# c. 根据 Map 条件查询用户信息
/**
* 根据 Map 条件查询用户数据
* @param columnMap 包含查询条件的 Map
* @return 返回查询到的实体对象列表
*/
@Test
public void testSelectByMap(){
Map<String, Object> map = new HashMap<>();
map.put("age", 18); // 示例:查询 age = 18 的记录
List<User> users = userMapper.selectByMap(map); // 根据 Map 条件查询
users.forEach(System.out::println);
}
2
3
4
5
6
7
8
9
10
11
12
# d. 查询所有用户信息
/**
* 查询所有用户数据
* @param queryWrapper 查询条件构造器
* @return 返回查询到的实体对象列表
*/
@Test
void testSelectList(){
List<User> users = userMapper.selectList(null); // 查询所有数据
users.forEach(System.out::println);
}
2
3
4
5
6
7
8
9
10
重要 API 说明:
T selectById(Serializable id)
:根据 ID 查询单条记录。List<T> selectBatchIds(Collection<? extends Serializable> idList)
:根据 ID 列表批量查询记录。List<T> selectByMap(Map<String, Object> columnMap)
:根据 Map 条件查询记录。- 参数:
Map<String, Object> columnMap
- 查询条件 Map,键为列名,值为条件值。
- 参数:
List<T> selectList(Wrapper<T> queryWrapper)
:查询所有记录或根据条件查询记录。- 参数:
Wrapper<T> queryWrapper
- 查询条件构造器(可以为null
查询所有记录)。
- 参数: