SmartMapper API

郭胜凯2026/08/17

业务 Mapper 继承 SmartMapper<T extends PO> 后,会获得通用 CRUD、条件查询、分页、关联和原始 SQL 能力。它仍然是普通 MyBatis Mapper,可以继续声明 XML 或注解 SQL。

@Mapper
public interface StudentMapper extends SmartMapper<Student> {
}

API 一览

类型方法返回值/说明
插入insert(record)插入一条,AUTO 主键回填到对象
插入insertBatch(records)批量插入,行为由数据库方言适配
查询selectAll()查询全部记录
查询select(where)按条件查询列表
查询selectWithRelations(where)查询并自动填充声明的关联字段
查询selectById(id)按主键查询
查询selectOne(where)期望至多一条,多条时由 MyBatis 抛出异常
查询selectFirst(where)为传入条件追加 limit(1),返回第一条或 null
分页selectPage(where, page)先 count,再查询当前页
统计count()count(where)全表或按条件计数
更新updateById(record)按主键更新所有映射的非主键字段
删除deleteById(id)按主键删除
删除deleteByIds(ids)按主键集合删除
删除delete(where)按条件删除
原始 SQLqueryBySql(...)返回 List<Map<String,Object>>
原始 SQLexecuteSql(...)执行更新/DDL,返回影响行数
SQL 脚本executeSqlScript(script)拆分并逐条执行可信脚本

常用查询

Student byId = studentMapper.selectById(1);

Student first = studentMapper.selectFirst(
    Where.where(Student::getName).like("张")
         .orderBy(Student::getId).asc()
);

long adults = studentMapper.count(
    Where.where(Student::getAge).gte(18)
);

selectOne 适合唯一条件;如果业务语义只是“取第一条”,应使用 selectFirst 并明确排序。

分页

Where where = Where.where(Student::getAge).gte(18)
    .orderBy(Student::getId).asc();

PageResult<Student> result = studentMapper.selectPage(
    where,
    new Page(1, 20)
);
  • 页码从 1 开始。
  • Page() 默认第 1 页、每页 10 条。
  • PageResult 包含 data/total/page/pageSize/totalPages
  • 分页应带稳定排序,并限制最大 pageSize

Where

selectFirst 会对传入的 Where 设置 limit(1)selectPage 也会写入分页 limit。不要跨请求、线程或多个不同查询复用同一个 Where

更新语义

updateById 是全字段更新,不是“仅更新非空字段”:

Student student = studentMapper.selectById(id);
student.setAge(21);
studentMapper.updateById(student);

不要只创建一个包含 id 和少数字段的残缺对象直接更新,否则其他映射字段可能被写入 null 或 Java 基础类型默认值。局部更新更适合声明一个明确的 MyBatis 方法或使用绑定参数的 executeSql

删除安全

if (ids == null || ids.isEmpty()) {
    return 0;
}
return studentMapper.deleteByIds(ids);

不要把可能为空的动态条件直接用于删除。delete(Where.where()) 会成为无条件删除;notIn(emptyCollection) 会退化为恒真条件,也可能扩大删除范围。

批量插入

insertBatch 不接受 null 或空集合。AUTO 主键回填由当前方言和 Mapper 初始化器配合完成。Oracle 会在框架内部复用基础 insert,其他内置方言通常生成一条批量 SQL。

应用只应调用公开的 insertBatchinsertBatchSql 是框架内部承接批量 SQL 的方法,不建议业务直接调用。

尚未实现的 API

3.0.2 中 selectTrees(where, parentFunc, idFunc) 仍会抛出 The method is not implemented yet.。在正式实现和测试发布前,不要在业务中使用它。