Skip to content

快速开始

krismile-boot3-starter-mybatisplus 是基于 MyBatis-Plus 的增强模块,提供了开箱即用的数据持久层解决方案,包括基础实体类、增强 Service 层、自动填充、数据校验等功能。

核心特性

  • 基础实体类BaseDOBaseAssignDO 提供标准字段和雪花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 Boot3.5.8基础框架
MyBatis-Plus3.5.14ORM 框架
Druid1.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 上下文,请确保:

  1. 请求经过了框架的过滤器/拦截器
  2. 在拦截器中正确设置了 RequestInfo.REQUEST_CONTEXT
  3. 实体类中定义了 createUserupdateUser 字段

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;

下一步

扩展阅读

Released under the Apache-2.0 License