用于在使用 xbatis 的 Java 项目中实现、改写、审查或优化 ORM、Mapper、QueryChain、联表、分页、VO 映射、多租户、逻辑删除、乐观锁、SQL 模板相关代码。适用于 Spring Boot 2/3/4、Solon,以及需要 AI Agent 严格...
Xbatis Skills是一项面向实际任务的技能,主要用于使用这份 Skills 时,优先遵循 xbatis 的原生表达方式,不要把它当成其他 ORM 或传统 XML MyBatis 使用;处理以下任务时,使用这份 Skill:;
它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。
执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
使用这份 Skills 时,优先遵循 xbatis 的原生表达方式,不要把它当成其他 ORM 或传统 XML MyBatis 使用。
处理以下任务时,使用这份 Skill:
BasicMapper、MybatisMapper、QueryChain、UpdateChain、InsertChain、DeleteChain不要将这份 Skill 用于:
始终按以下顺序决策:
始终保持以下优先级:
queryChain() / updateChain() / insertChain() / deleteChain()returnType避免以下默认倾向:
默认按以下项目级约束生成和审查代码:
@XbatisPojoCheckScan 接入;README 记录的包名是 org.mybatis.spring.boot.autoconfigure.XbatisPojoCheckScan,但生成前必须从当前项目依赖或本地 starter 源码确认真实包名solon.yml 的 mybatis.<数据源 bean 名称>.pojoCheck 下配置 basePackages、modelPackages、resultEntityPackages、conditionTargetPackages、orderByTargetPackagesbasePackages 覆盖项目相关包,要么使用 modelPackages / resultEntityPackages / conditionTargetPackages / orderByTargetPackages 等细分包路径;不要同时生成两种方案@FieldNameConstants 支持字段常量引用按任务读取对应参考文件,不要一次性加载全部 references:
@MapperScan 时,读取 references/environment-setup.mdreferences/query-strategy.mdBasicMapper 时,读取 references/mapper-modes.mdreferences/framework-features.mdreferences/advanced-sql.mdreferences/xml-boundaries.mdreferences/review-checklist.md启用 xbatis 任务时,先做这件事:
https://github.com/xbatis/xbatishttps://gitee.com/xbatis/xbatishttps://github.com/xbatis/xbatis-spring-boot-parenthttps://gitee.com/xbatis/xbatis-spring-boot-parenthttps://github.com/xbatis/xbatis-solon-pluginhttps://gitee.com/xbatis/xbatis-solon-plugin先将任务归类为以下一种:
优先使用:
getByIdgetValueByIdBasicDaoImplDaoImpl避免:
QueryChain优先使用:
queryChain()paging(Pager)避免:
forSearch(true)只有搜索查询、搜索表单、后台筛选页、关键词查询才优先使用 forSearch(true)。
优先使用:
queryChain()@Fetch,不要默认写 join.from(...) 明确主表returnType(VO.class)select(VO.class) 或实体/VO 自动列推导@PutEnumValue避免:
@Fetch 的场景机械改成 joinselect 字段,本可直接 select(VO.class) 却堆大量列优先使用:
updateChain()insertChain()deleteChain()避免:
UpdateChain.of(...)InsertChain.of(...)DeleteChain.of(...)DeleteChain 当成逻辑删除入口优先使用:
最后再考虑:
避免:
落代码前,先确认:
已有明确风格时,跟随项目,不要引入另一套 ORM 写法。
新项目或用户未指定模式时,优先推荐单 Mapper + DAO。
默认执行以下规则:
@Table@TableId@TableField@FieldNameConstants仅在以下场景补更多注解:
推荐的字段规则:
@TableField(defaultValue = "{NOW}", update = false)@TableField(defaultValue = "{NOW}", updateDefaultValue = "{NOW}", updateDefaultValueFillAlways = true)@TableField("xxx")@TableField@Ignore 或 @Ignores避免:
@TableField默认执行以下规则:
XbatisMapper extends BasicMapperXbatisGlobalConfig.setSingleMapperClass(...)BasicDaoImplDaoImplcn.xbatis.core.mvc.DaosetMapper(...) 方法必须加上当前容器框架的自动注入注解;Spring 跟随 @Autowired / @Resource 等项目既有规范,Solon 跟随 @Inject / @Db 等项目既有规范setMapper(...)cn.xbatis.core.mvc.IDao;源码注释说明 IDao 是旧接口且不建议开发者使用避免:
IDao,或不建接口只建实现类重点执行:
references/mapper-modes.mdsetMapper(...),内部调用父类 setMapper(mapper) 完成绑定Dao;业务 DAO 实现类继承项目 BaseDao 并实现该接口setMapper(...)findById、create、modify 这类二次命名@MapperScan 扫描统一 XbatisMapper 所在包;如果项目已使用 markerInterface = BasicMapper.class,延续现有配置XbatisGlobalConfig.setSingleMapperClass(...)默认执行以下规则:
cn.xbatis.core.mybatis.typeHandler.EnumSupportcode 值并实现 getCode();字段类型 T 按数据库实际存储类型选择,例如 String、Integer、Longpublic static Xxx of(T code) 方法;遍历枚举按 code 匹配,找不到时返回 nullpublic enum Status implements EnumSupport { ... } Enum.name()、ordinal() 或手写 TypeHandler 作为 xbatis 枚举持久化方案@PutEnumValue示例:
public enum Status implements EnumSupport{ ENABLED(1), DISABLED(0); private final Integer code; Status(Integer code) { this.code = code; } @Override public Integer getCode() { return code; } public static Status of(Integer code) { for (Status item : values()) { if (java.util.Objects.equals(item.getCode(), code)) { return item; } } return null; } }
生成前必须从本地 xbatis 源码确认真实包名;当前源码中 EnumSupport 位于 cn.xbatis.core.mybatis.typeHandler.EnumSupport。
默认执行以下规则:
queryChain()cn.xbatis.core.mvc.QO 并提供 where()@ConditionTarget、@Condition、@Conditions、@ConditionGroup 等对象转条件注解@Ignore 或 @IgnoresforSearch(true)paging(Pager)@Fetch.from(...) 明确主表leftJoin(SysUser::getRoleId, SysRole::getId) 这类带方法引用的写法,第二个参数所属实体是被 join 的实体select(VO.class);如果 returnType 与 select 类型一致且没有额外 select,可省略 .select(...)按 id 查询:
getByIdgetValueByIdqueryChain()额外检查:
leftJoin 分页优化是否合适,必要时改用 rightJoin() 或关闭 join 优化避免:
@Fetch 的场景机械使用 joinforSearch(true)forSearch(true) 时,仍把值忽略判断散落成外层 if.eq(SysUser::getId, id, Objects::nonNull),却使用更绕的写法or 条件时,没有使用 .nested(chain -> ...)select 字段,本可直接 select(VO.class) 却堆大量列注意:源码接口名是 QO,不要写成 Qo。
注意:QO.where() 中优先使用 WhereUtil.where(this) 写法。
无法使用 forSearch(true),但需要根据值忽略条件时:
.eq(SysUser::getId, id, Objects::nonNull)when 重载,例如 .eq(Objects.nonNull(id), SysUser::getId, id)or 条件时,使用 .nested(chain -> ...)and;调用 .or() 后会持续使用 or,需要切回时显式调用 .and()or 条件优先放进 .nested(...),避免 .or() 状态影响后续外层条件默认执行以下规则:
updateChain()insertChain()deleteChain()UpdateChain、InsertChain、DeleteChain 最终执行方法统一是 execute()save(Model)、update(Model), xbatis 自带这些方法@Ignore 或 @IgnorespartialUpdate(...) 精准修改避免:
UpdateChain.of(...)、InsertChain.of(...)、DeleteChain.of(...)BasicMapper 的 Chain 创建方式partialUpdate(...) 精准修改,却直接对查出的实体做普通 update(entity)UpdateChain、InsertChain、DeleteChain 却没有以 execute() 收尾默认执行以下规则:
@ResultEntity、@NestedResultEntity、@NestedResultEntityField、@ResultCalcField 等结果映射注解@PutEnumValue@Ignore 或 @Ignores避免:
@Table、@TableId、@TableField 等实体类注解将 XML / 原生 SQL 视为后置选项。
仅在以下场景使用:
使用 SQL 模板时:
Methods.tpl(...)Methods.fTpl(...)Methods.cTpl(...)避免在以下场景使用:
优先复用框架逻辑删除能力。
避免:
deleted = 0DeleteChain 删除不触发逻辑删除规则deleteChain()优先使用 @TenantId 和框架多租户能力。
避免:
tenant_id优先使用 @Version。
避免:
优先使用全局动态值、@OnInsert、@OnUpdate。
避免:
实体审计字段建议:
@TableField(defaultValue = "{NOW}", update = false)@TableField(defaultValue = "{NOW}", updateDefaultValue = "{NOW}", updateDefaultValueFillAlways = true)优先将搜索对象、筛选对象、排序对象交给框架对象转换能力处理。
查询对象规则:
cn.xbatis.core.mvc.QOQO.where() 负责集中构建 Where@ConditionTarget,并按需使用 @Condition、@Conditions、@ConditionGroupQO.where() 中优先使用 WhereUtil.where(this)queryChain(qo.where())Methods 风格时,优先静态导入所需方法,并保持 eq(gt(...)) 这类嵌套表达避免:
iforder by将以下行为视为明显偏离 xbatis 风格:
forSearch(true) 与空值忽略能力forSearch(true)QO 表达的查询条件却散落在 Service 层getById / getValueByIdwhen 重载or 条件时,不使用 .nested(...).or() 后没有显式 .and() 切回,导致后续条件错误变成 OR@TableField("列名")@TableField 的动态默认值能力@ConditionTarget 体系和 WhereUtil.where(this)setMapper(...) 重复写在每个业务 DAO 子类里,而不是在项目 BaseDao 上统一加容器自动注入注解SysUser.Fields.id.as(...) 明明可以使用字段 / getter 引用,却默认回退字符串别名@Ignore 或 @IgnorespartialUpdate(...) 精准修改UpdateChain、InsertChain、DeleteChain 却没有调用 execute()Methods.tpl、Methods.fTpl、Methods.cTpl 创建提交前,逐项检查:
forSearch(true) 是否只用于搜索查询cn.xbatis.core.mvc.QOgetById / getValueByIdwhen 重载or 的成组条件是否使用 .nested(...).or() 后是否已在需要时通过 .and() 切回.from(...)、方法引用 join 和 select(VO.class)@FetchXbatisMapper 并配置 @MapperScan@PutEnumValue@TableField("列名")@TableField(defaultValue = "{NOW}", update = false) 和 @TableField(defaultValue = "{NOW}", updateDefaultValue = "{NOW}", updateDefaultValueFillAlways = true)@ConditionTarget 体系,并在 where() 中使用 WhereUtil.where(this)setMapper(...) 是否带 Spring、Solon 等容器自动注入注解,业务 DAO 子类是否避免重复重写 setMapper(...)@FieldNameConstants 生成的 Fields.as(...) 是否优先使用 getter / 字段引用形式,例如 .select(SysUser::getId, c -> c.as(SysUser::getId))@Ignore 或 @IgnorespartialUpdate(...) 精准修改UpdateChain、InsertChain、DeleteChain 是否最终使用 execute() 执行Methods.tpl、Methods.fTpl、Methods.cTpl 创建执行:
cn.xbatis.core.mvc.QO@ConditionTarget、@Condition、@Conditions、@ConditionGroup@Ignore 或 @Ignoreswhere() 中优先使用 WhereUtil.where(this)queryChain(qo.where())forSearch(true),其他场景使用对象转条件、predicate / boolean when 或显式条件paging(Pager)执行:
queryChain().from(...) 明确主表,再定义 joinleftJoin(SysUser::getRoleId, SysRole::getId)returnType(VO.class);需要时优先 select(VO.class)@ResultEntity 等结果映射注解;必要时补 @PutEnumValue@Ignore 或 @Ignores执行:
@TableField(defaultValue = "{NOW}", update = false)@TableField(defaultValue = "{NOW}", updateDefaultValue = "{NOW}", updateDefaultValueFillAlways = true)@OnInsert@OnUpdate始终记住这些规则:
QO 对象转条件并在 DAO 内执行getById,按 id 查单列值用 getValueByIdforSearch(true)@Fetch,真正需要 join 时先 .from(...),再用方法引用 joinQO 并使用 @ConditionTarget 体系;QO.where() 优先用 WhereUtil.where(this)when 重载;成组 or 条件用 .nested(...),.or() 后需要时用 .and() 切回;使用 Methods 风格时优先静态导入select(VO.class) / returnType(VO.class) 自动映射,VO 优先配合 @ResultEntity 等结果映射注解@PutEnumValue@TableField;创建时间优先 @TableField(defaultValue = "{NOW}", update = false),修改时间优先 @TableField(defaultValue = "{NOW}", updateDefaultValue = "{NOW}", updateDefaultValueFillAlways = true)@Ignore 或 @Ignores@FieldNameConstants 和 SysUser.Fields.id 这类字段引用.as(...) 优先使用 getter / 字段引用形式,例如 .select(SysUser::getId, c -> c.as(SysUser::getId));只有特殊情况才使用 .as("id")setMapper(...) 上,并补 Spring、Solon 等容器自动注入注解;BaseDao 子类不重复重写 setMapper(...),不默认走构造方法传 MapperpartialUpdate(...) 精准修改UpdateChain、InsertChain、DeleteChain 最终统一通过 execute() 执行Methods.tpl、Methods.fTpl、Methods.cTpl 创建XbatisMapper extends BasicMapper 并配置 @MapperScan,不主动调用 XbatisGlobalConfig.setSingleMapperClass(...)basePackages 和细分包路径中二选一;测试和生产环境不要求默认开启;不知道真实注解包名或配置项时,先查当前 starter 依赖和本地源码如果生成结果不满足这些规则,继续收敛实现方案。