BaseMapper 接口是 MyBatis-Plus 提供的一个基础 Mapper 接口,它定义了一系列的通用数据库操作方法,包括插入、更新、删除和查询等。通过继承 BaseMapper,我们可以直接使用其中定义的方法来执行数据库操作,无需编写繁琐的 SQL 语句和 XML 映射文件。BaseMapper 封装了底层的数据库访问逻辑,提供了一种更简洁和方便的方式来进行 CRUD 操作。
MyBatis-Plus 提供了基础的 CRUD(增删改查)操作,通过继承 BaseMapper
接口,可以直接使用 MyBatis-Plus 提供的方法来执行数据库的增删改查操作,无需编写繁琐的 SQL 语句和 XML 映射文件。以下是 MyBatis-Plus 的基础 CRUD 操作示例:
@Data
@TableName("user")
public class User {
@TableId
private Long id;
private String username;
private String email;
}
public interface UserMapper extends BaseMapper<User> {}
@Autowired
private UserMapper userMapper;
public void insertUser(User user) {
userMapper.insert(user);
}
通过调用 userMapper.insert(user)
方法可以插入一条数据到数据库中。
public User getUserById(Long id) {
return userMapper.selectById(id);
}
通过调用 userMapper.selectById(id)
方法可以根据主键查询对应的数据。
public void updateUser(User user) {
userMapper.updateById(user);
}
通过调用 userMapper.updateById(user)
方法可以根据主键更新对应的数据。
public void deleteUserById(Long id) {
userMapper.deleteById(id);
}
通过调用 userMapper.deleteById(id)
方法可以根据主键删除对应的数据。
这些示例展示了 MyBatis-Plus 的基础 CRUD 操作。通过继承 BaseMapper
接口,我们可以直接使用其中的方法来执行数据库的增删改查操作,无需手动编写 SQL 语句和 XML 映射文件,简化了开发过程。
这是BaseMapper接口内部的提供的crud的方法
/**
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
* 这个 Mapper 支持 id 泛型
*
* @author hubin
* @since 2016-01-23
*/
public interface BaseMapper<T> extends Mapper<T> {
/**
* 插入一条记录
*
* @param entity 实体对象
*/
int insert(T entity);
/**
* 根据 ID 删除
*
* @param id 主键ID
*/
int deleteById(Serializable id);
/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,删除记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 根据 ID 修改
*
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根据 whereEntity 条件,更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 查询(根据 columnMap 条件)
*
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* 注意: 只返回第一个字段的值
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
ServiceImpl 则是在 BaseMapper 的基础上进一步封装的一个抽象类,用于实现 Service 层的基本操作。它提供了一系列的方法来执行数据库的增删改查操作,包括插入、更新、删除、查询等。通过继承 ServiceImpl,我们可以直接使用其中的方法来进行数据库操作,无需手动编写常见的数据库操作方法。ServiceImpl 进一步简化了 Service 层的代码编写,提高了开发效率。
ServiceImpl
是 MyBatis-Plus 提供的一个抽象类,用于实现 Service 层的基本操作。下面是 ServiceImpl
的使用方式:
创建实体类和 Mapper 接口:
@Data
@TableName("user")
public class User {
@TableId
private Long id;
private String username;
private String email;
}
public interface UserMapper extends BaseMapper<User> {
}
创建 Service 接口和实现类,并继承 ServiceImpl
:
public interface UserService {
void saveUser(User user);
User getUserById(Long id);
void updateUser(User user);
void deleteUserById(Long id);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public void saveUser(User user) {
this.save(user);
}
@Override
public User getUserById(Long id) {
return this.getById(id);
}
@Override
public void updateUser(User user) {
this.updateById(user);
}
@Override
public void deleteUserById(Long id) {
this.removeById(id);
}
}
在 UserServiceImpl
中,通过继承 ServiceImpl
,我们可以直接使用 ServiceImpl
中封装的方法来执行数据库操作,无需手动编写常见的数据库操作方法。例如,通过调用 this.save(user)
可以插入一条数据,通过调用 this.getById(id)
可以根据主键查询数据。
注意,要确保在 ServiceImpl
的泛型参数中传入正确的类型,第一个参数是 Mapper 接口,第二个参数是实体类类型。
在其他层或组件中注入并使用 Service:
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/users")
public void saveUser(@RequestBody User user) {
userService.saveUser(user);
}
@GetMapping("/users/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
// 其他接口和方法
}
在上述代码中,我们可以通过注入 UserService
来使用其中定义的方法。例如,调用 userService.saveUser(user)
可以保存一个用户,调用 userService.getUserById(id)
可以根据用户ID查询用户。
通过继承 ServiceImpl
,我们可以使用其中封装好的方法来执行数据库操作,无需手动编写常见的数据库操作方法,简化了代码的编写过程,提高了开发效率。同时,我们可以根据具体业务需求在 ServiceImpl
的基础上添加自定义的方法,实现更复杂的业务逻辑。
BaseMapper 和 ServiceImpl 都是对 MyBatis-Plus 的 CRUD 操作进行了封装。
条件构造器(Wrapper)在 MyBatis-Plus 中按照功能和用途可以分为三种类型:QueryWrapper、UpdateWrapper 和 LambdaQueryWrapper。下面将对每种类型进行分类说明,并展示其使用方式。
QueryWrapper:
QueryWrapper 用于构建查询条件,适用于 SELECT 操作。
示例代码:
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John") // 等于条件
.ne("age", 25) // 不等于条件
.like("email", "@gmail.com") // 模糊匹配条件
.between("age", 20, 30) // 范围查询条件
.orderByAsc("age"); // 排序条件
List<User> userList = userMapper.selectList(queryWrapper);
UpdateWrapper:
UpdateWrapper 用于构建更新条件,适用于 UPDATE 操作。
示例代码:
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("email", "[email protected]") // 设置更新字段
.eq("name", "John") // 等于条件
.ne("age", 25); // 不等于条件
int affectedRows = userMapper.update(null, updateWrapper);
LambdaQueryWrapper:
LambdaQueryWrapper 是基于 Lambda 表达式的条件构造器,提供了更加类型安全的查询方式。
示例代码:
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(User::getName, "John") // 等于条件
.ne(User::getAge, 25) // 不等于条件
.likeRight(User::getEmail, "@gmail.com") // 模糊匹配条件,右侧模糊匹配
.between(User::getAge, 20, 30) // 范围查询条件
.orderByAsc(User::getAge); // 排序条件
List<User> userList = userMapper.selectList(lambdaQueryWrapper);
通过选择合适的条件构造器类型,我们可以根据具体的操作类型和需求,灵活地构建查询条件或更新条件。这些条件构造器提供了丰富的方法来支持各种条件的组合和操作符的使用,使得查询条件或更新条件的编写更加简洁和易于理解。通过链式调用方法,我们可以便捷地构建复杂的条件,并通过相应的 MyBatis-Plus 方法来执行数据库操作。
使用 @Select
和 @Results
注解可以实现一对多和多对一的映射查询。下面分别介绍如何使用这两个注解实现一对多和多对一的映射查询:
一对多关系映射查询示例(以用户和订单为例):
@Data
@TableName("user")
public class User {
@TableId
private Long id;
private String username;
@TableField(exist = false)
private List<Order> orders;
}
@Data
@TableName("order")
public class Order {
@TableId
private Long id;
private String orderNo;
private Long userId;
}
@Select
注解编写查询 SQL,并使用 @Results
注解指定映射关系:@Mapper
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT u.*, o.id AS order_id, o.order_no FROM user u " +
"LEFT JOIN `order` o ON u.id = o.user_id " +
"WHERE u.id = #{userId}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "orders", column = "id", javaType = List.class, /* 这里的id是要传递给下面查询里需要的参数,对应的是上面@Select注解中SQL查询出的user表的id,而这个id对应的是order表中的userID,传递到下面要调用的selectByUserId方法需要的userId参数*/,
many = @Many(select = "com.example.mapper.OrderMapper.selectByUserId"))
})
User selectUserWithOrders(@Param("userId") Long userId);
}
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
@Select("SELECT * FROM `order` WHERE user_id = #{userId}")
List<Order> selectByUserId(@Param("userId") Long userId);
}
在 @Results
注解中,通过 @Result
注解指定实体类属性和数据库列之间的映射关系。其中,@Result
注解中的 property
属性指定实体类中的属性名,column
属性指定数据库查询结果集中的列名。在 @Result
注解中使用 @Many
注解指定一对多关系中多的一方的查询方法。
多对一关系映射查询示例(以订单和用户为例):
@Data
@TableName("order")
public class Order {
@TableId
private Long id;
private String orderNo;
private Long userId;
@TableField(exist = false)
private User user;
}
@Data
@TableName("user")
public class User {
@TableId
private Long id;
private String username;
}
@Select
注解编写查询 SQL,并使用 @Results
注解指定映射关系:@Mapper
public interface OrderMapper extends BaseMapper<Order> {
@Select("SELECT o.*, u.id AS user_id, u.username FROM `order` o " +
"LEFT JOIN user u ON o.user_id = u.id " +
"WHERE o.id = #{orderId}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "orderNo", column = "order_no"),
@Result(property = "user", column
= "user_id",
one = @One(select = "com.example.mapper.UserMapper.selectById"))
})
Order selectOrderWithUser(@Param("orderId") Long orderId);
}
@Mapper
public interface UserMapper extends BaseMapper<User> {
@Select("SELECT * FROM user WHERE id = #{userId}")
User selectById(@Param("userId") Long userId);
}
在 @Results
注解中,通过 @Result
注解指定实体类属性和数据库列之间的映射关系。其中,@Result
注解中的 property
属性指定实体类中的属性名,column
属性指定数据库查询结果集中的列名。在 @Result
注解中使用 @One
注解指定多对一关系中一的一方的查询方法。