快速开始
krismile-boot3-starter-mybatisplus 是基于 MyBatis-Plus 的增强模块,提供了开箱即用的数据持久层解决方案,包括基础实体类、增强 Service 层、自动填充、数据校验等功能。
核心特性
- ✅ 基础实体类:
BaseDO、BaseAssignDO提供标准字段和雪花ID支持 - ✅ 增强 Service 层:
BaseService提供 Ignore/Validate 双模式方法 - ✅ 自动填充:自动填充创建时间、修改时间、创建人、修改人
- ✅ 数据校验:
@DatabaseExistsById校验数据库存在性 - ✅ 悲观锁支持:
getAndLock系列方法支持for update查询 - ✅ 关联查询:
parseRelObject方法简化关联对象查询
依赖引入
Maven 依赖
在项目的 pom.xml 中添加依赖:
xml
<dependency>
<groupId>host.springboot.framework</groupId>
<artifactId>krismile-boot3-starter-mybatisplus</artifactId>
<version>0.1.0</version>
</dependency>版本说明
| 组件 | 版本 | 说明 |
|---|---|---|
| Spring Boot | 3.5.8 | 基础框架 |
| MyBatis-Plus | 3.5.14 | ORM 框架 |
| Druid | 1.2.27 | 数据库连接池(可选) |
| MySQL Connector | 最新 | MySQL 驱动(可选) |
数据库配置
application.yml 配置示例
yaml
spring:
# 数据源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: your_password
# Druid 连接池配置(可选)
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
# MyBatis-Plus 配置
mybatis-plus:
# 实体类扫描路径
type-aliases-package: com.example.domain
# Mapper XML 文件路径
mapper-locations: classpath*:/mapper/**/*.xml
# 全局配置
global-config:
db-config:
# 主键类型(雪花算法)
id-type: assign_id
# 逻辑删除字段
logic-delete-field: logicDelete
logic-delete-value: 1
logic-not-delete-value: 0
# MyBatis 配置
configuration:
# 驼峰命名转换
map-underscore-to-camel-case: true
# 日志实现
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl快速上手
1. 定义实体类
继承 BaseAssignDO 获得标准字段和雪花ID:
java
import host.springboot.framework.mybatisplus.domain.BaseAssignDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
public class User extends BaseAssignDO {
/**
* 用户名
*/
private String username;
/**
* 邮箱
*/
private String email;
/**
* 手机号
*/
private String phone;
/**
* 状态(0: 禁用, 1: 启用)
*/
private Integer status;
}继承 BaseAssignDO 后,实体类自动拥有以下字段:
java
private Long id; // 主键(雪花ID)
private LocalDateTime createTime; // 创建时间(自动填充)
private String createUser; // 创建人(自动填充)
private LocalDateTime updateTime; // 修改时间(自动填充)
private String updateUser; // 修改人(自动填充)2. 创建 Mapper 接口
java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 继承 BaseMapper 即可,无需编写任何方法
}3. 创建 Service 接口
继承 BaseService 获得增强的 CRUD 方法:
java
import host.springboot.framework.mybatisplus.service.BaseService;
public interface UserService extends BaseService<User> {
// 继承 BaseService 即可获得丰富的 CRUD 方法
}4. 创建 Service 实现类
java
import host.springboot.framework.mybatisplus.service.BaseServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User>
implements UserService {
// 继承 BaseServiceImpl 即可,无需编写任何方法
}5. Controller 使用示例
java
import host.springboot.framework3.core.vo.SingleVO;
import host.springboot.framework3.core.vo.MultiVO;
import host.springboot.framework3.core.vo.PageVO;
import host.springboot.framework3.core.page.Pageable;
import host.springboot.framework3.core.page.query.PageQuery;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
/**
* 根据ID查询用户(容错模式)
*/
@GetMapping("/{id}")
public SingleVO<User> getById(@PathVariable Long id) {
// 如果 id 为 null 或不存在,返回 null 而不抛异常
User user = userService.getByIdIgnore(id);
return R.okSingle(user);
}
/**
* 根据ID查询用户(严格校验模式)
*/
@GetMapping("/validate/{id}")
public SingleVO<User> getByIdValidate(@PathVariable Long id) {
// 如果 id 为 null 或不存在,抛出 MybatisServiceException
User user = userService.getByIdValidate(id);
return R.okSingle(user);
}
/**
* 查询用户列表
*/
@GetMapping("/list")
public MultiVO<User> list() {
List<User> users = userService.list();
return R.okMulti(users);
}
/**
* 分页查询用户
*/
@GetMapping("/page")
public PageVO<User> page(PageQuery pageQuery) {
// 自动按 updateTime 降序排序
Pageable<List<User>> page = userService.pageIgnore(pageQuery);
return R.okPage(page);
}
/**
* 创建用户
*/
@PostMapping
public BaseVO create(@RequestBody User user) {
// createTime、updateTime、createUser、updateUser 自动填充
userService.saveIgnore(user);
return R.ok("创建成功");
}
/**
* 更新用户
*/
@PutMapping
public BaseVO update(@RequestBody User user) {
// updateTime、updateUser 自动填充
userService.updateByIdIgnore(user);
return R.ok("更新成功");
}
/**
* 删除用户
*/
@DeleteMapping("/{id}")
public BaseVO delete(@PathVariable Long id) {
userService.removeByIdIgnore(id);
return R.ok("删除成功");
}
}核心方法说明
Ignore 系列方法(容错模式)
特点:参数为 null 或数据不存在时不抛异常,返回默认值。
| 方法 | 说明 | 返回值 |
|---|---|---|
getByIdIgnore(id) | 根据ID查询 | null(不存在时) |
listByIdIgnore(ids) | 根据ID列表查询 | 空集合(不存在时) |
pageIgnore(pageQuery) | 分页查询 | 空分页对象 |
saveIgnore(entity) | 保存实体 | null(参数为null时) |
updateByIdIgnore(entity) | 更新实体 | false(参数为null时) |
removeByIdIgnore(id) | 删除实体 | false(参数为null时) |
Validate 系列方法(严格校验模式)
特点:参数为 null 或数据不存在时抛出 MybatisServiceException。
| 方法 | 说明 | 异常情况 |
|---|---|---|
getByIdValidate(id) | 根据ID查询 | ID为null 或 数据不存在 |
listByIdValidate(ids) | 根据ID列表查询 | IDs为null/empty 或 数据不完整 |
pageValidate(pageQuery) | 分页查询 | pageQuery为null |
saveValidate(entity) | 保存实体 | entity为null |
updateByIdValidate(entity) | 更新实体 | entity为null 或 ID不存在 |
removeByIdValidate(id) | 删除实体 | ID为null 或 数据不存在 |
使用建议
- Ignore 模式:适用于前端展示、可选数据查询等场景
- Validate 模式:适用于核心业务逻辑、必须保证数据存在的场景
自动填充说明
框架会自动填充以下字段(需要在实体类中定义):
插入时自动填充
java
createTime = LocalDateTime.now(); // 创建时间
updateTime = LocalDateTime.now(); // 修改时间
createUser = RequestInfo.getUserId(); // 创建人(从请求上下文获取)
updateUser = RequestInfo.getUserName(); // 修改人(从请求上下文获取)更新时自动填充
java
updateTime = LocalDateTime.now(); // 修改时间
updateUser = RequestInfo.getUserId(); // 修改人(从请求上下文获取)提示
自动填充依赖 RequestInfo 上下文,确保请求经过框架的过滤器或拦截器处理。
数据库表设计建议
为了充分利用框架的自动填充功能,建议按以下规范设计表结构:
sql
CREATE TABLE `sys_user` (
`id` BIGINT(20) NOT NULL COMMENT '主键ID',
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
`email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱',
`phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
`status` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '状态(0:禁用,1:启用)',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`create_user` VARCHAR(50) DEFAULT NULL COMMENT '创建人',
`update_time` DATETIME NOT NULL COMMENT '修改时间',
`update_user` VARCHAR(50) DEFAULT NULL COMMENT '修改人',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';常见问题
Q: 如何自定义主键生成策略?
A: 可以在实体类中使用 @TableId 注解:
java
@TableId(value = "id", type = IdType.AUTO) // 自增主键
private Long id;
@TableId(value = "id", type = IdType.ASSIGN_UUID) // UUID
private String id;Q: 为什么 createUser 和 updateUser 没有自动填充?
A: 自动填充依赖 RequestInfo 上下文,请确保:
- 请求经过了框架的过滤器/拦截器
- 在拦截器中正确设置了
RequestInfo.REQUEST_CONTEXT - 实体类中定义了
createUser和updateUser字段
Q: Ignore 和 Validate 方法如何选择?
A:
- Ignore:适用于可选查询、展示类场景,容忍数据不存在
- Validate:适用于核心业务逻辑,必须保证数据存在
例如:
java
// 展示用户信息 - 使用 Ignore
User user = userService.getByIdIgnore(userId);
if (user != null) {
// 展示用户信息
}
// 更新用户信息 - 使用 Validate
User user = userService.getByIdValidate(userId); // 不存在直接抛异常
user.setEmail(newEmail);
userService.updateByIdValidate(user);Q: 如何禁用自动填充?
A: 在实体类字段上使用 @TableField 注解:
java
@TableField(fill = FieldFill.DEFAULT) // 禁用自动填充
private LocalDateTime createTime;下一步
- 基础实体类 - 了解
BaseDO和BaseAssignDO的详细用法 - 增强 Service 层 - 深入学习
BaseService的所有方法 - 校验与检查 - 使用
@DatabaseExistsById进行数据校验 - 自动填充 - 自定义自动填充逻辑
