Skip to content

自定义 SQL 本地开发使用教程

这篇文档面向日常开发者,目标是把平台上的自定义 SQL 纳入本地项目维护:在本地创建、拉取、编辑、校验、推送、执行验证和删除,减少“平台上改了一版、本地不知道”的漂移。

适用场景:

  • 需要写复杂查询、跨表统计、报表 SQL。
  • 需要把已有平台 SQL 拉到本地长期维护。
  • 需要让 SQL 文件进入代码评审、版本管理或 AI Agent 工作流。
  • 需要在推平台前先做本地校验和变更预览。

不适用场景:

  • 简单数据 CRUD,优先用 SDK filter/getOne/create/update/delete
  • 简单分组汇总,优先考虑 SDK aggregate
  • 跨系统调用、事务编排、复杂业务逻辑,优先用 BFF。

1. 准备工作

确认当前项目已经有 .rabetbase.json,并且默认应用正确:

Bash
rabetbase app list --format json

如果一个项目配置了多个应用,先切换到你要操作的应用:

Bash
rabetbase app use <appName>

也可以不切默认应用,直接给单条命令加:

Bash
--app <appName>
# 或
--appcode <appCode>

确认当前 CLI 的 SQL 命令:

Bash
rabetbase sql --help

当前推荐主流程是:

Plain
list/detail -> create 或 pull -> 编辑本地文件 -> validate -> status -> push -> exec -> delete

2. 本地目录约定

CLI 会把 SQL 文件维护在项目根目录的:

Plain
.rabetbase/sql/<appCode>/<dbName|db-<id>>/<sqlCode>_<sqlName>.sql|xml

例如:

Plain
.rabetbase/sql/app-xxxxxxxx/order_db/2305f915-dd48cd4c_getOrderList.sql
.rabetbase/sql/app-xxxxxxxx/db-10001/2305f915-dd48cd4c_getOrderMapper.xml

同时会维护一个锁文件:

Plain
.rabetbase/sql.lock.json

锁文件记录:

  • 远端 SQL 的 remoteId
  • sqlCode
  • 当前文件路径
  • SQL 名称
  • 绑定数据库
  • 本地 hash
  • 远端版本号

开发者一般只需要编辑 .sql/.xml 文件,不要手动改 sql.lock.json


3. 查看平台上已有 SQL

先列出 SQL:

Bash
rabetbase sql list --format json

按名称搜索:

Bash
rabetbase sql list --name 用户 --format json

查看详情:

Bash
rabetbase sql detail --sqlcode <sqlCode> --format json

如果需要完整原始对象:

Bash
rabetbase sql detail --sqlcode <sqlCode> --verbose --format json

建议:不知道 sqlCode 时,先 list --name;拿到 sqlCode 后再 detail


4. 新建一条 SQL

新建 SQL 使用:

Bash
rabetbase sql create --name <sqlName> --db-id <dbId> --mode sql --yes --format json

MyBatis XML 模式:

Bash
rabetbase sql create --name <sqlName> --db-id <dbId> --mode mybatisXml --yes --format json

正式执行前可以先预览:

Bash
rabetbase sql create --name <sqlName> --db-id <dbId> --mode sql --dry-run --format json

创建成功后,CLI 会:

  • 在平台创建 SQL。
  • 拿到服务端生成的 sqlCode
  • .rabetbase/sql/<appCode>/<dbName|db-<id>>/ 生成本地文件。
  • 写入 .rabetbase/sql.lock.json

生成的本地文件会带 @lovrabet 头注释,例如:

SQL
-- @lovrabet.sqlCode: 2305f915-dd48cd4c
-- @lovrabet.sqlName: getUserList
-- @lovrabet.dbId: 10001
-- @lovrabet.dbName: order_db
-- @lovrabet.mode: sql
-- @lovrabet.syncedAt: 2026-04-20T10:00:00.000Z

SELECT 1 AS id;

这些头注释用于本地识别和排查,sql push 上传时会自动剥离,不会写回平台 SQL 正文。


5. 拉取已有 SQL 到本地

如果 SQL 已经在平台上存在,先拉到本地再修改:

Bash
rabetbase sql pull --sqlcode <sqlCode> --format json

也可以按名称批量拉取:

Bash
rabetbase sql pull --name 用户 --format json

先预览会写哪些文件:

Bash
rabetbase sql pull --sqlcode <sqlCode> --dry-run --format json

如果本地文件和远端不一致,默认不会覆盖,会返回类似:

Plain
local differs from remote

确认要以远端覆盖本地时,再执行:

Bash
rabetbase sql pull --sqlcode <sqlCode> --force --format json

注意:--force 会覆盖本地未推送修改,使用前建议先看:

Bash
rabetbase sql status --format json

6. 编辑 SQL 文件

直接编辑生成或拉取下来的 .sql/.xml 文件。

普通 SQL 示例:

SQL
SELECT
  id,
  username,
  phone
FROM app_user
WHERE status = #{status}
ORDER BY create_time DESC;

MyBatis XML 示例:

XML
<select id="query" resultType="map">
  SELECT
    id,
    username,
    phone
  FROM app_user
  WHERE 1 = 1
  <if test="status != null">
    AND status = #{status}
  </if>
  ORDER BY create_time DESC
</select>

参数建议统一使用 #{paramName}。后续执行时,--params 的 key 要和 SQL 里的参数名一致。


7. 推送前先校验

校验本地文件:

Bash
rabetbase sql validate --file ./.rabetbase/sql/<appCode>/<dbName>/<sqlCode>_<sqlName>.sql --format json

也可以直接校验一段 SQL:

Bash
rabetbase sql validate --sql "SELECT * FROM app_user WHERE id = #{id}" --format json

校验会检查:

  • SQL 类型,如 SELECT/INSERT/UPDATE/DELETE/DDL
  • 是否包含危险语句
  • 引用的表名
  • #{param} / ${param} 参数

需要结合数据集做表名/列名交叉检查时:

Bash
rabetbase sql validate --file <filePath> --schemas <datasetCode1>,<datasetCode2> --format json

建议:写完 SQL 先 validate,再 status,最后 push


8. 查看本地状态

查看当前应用下 SQL 文件状态:

Bash
rabetbase sql status --format json

输出分类:

分类含义常见处理
added本地有,但 lock 里没有确认是否应通过 sql createsql pull 建立同步关系
modified本地文件相对 lock 有变化validate,再 push --dry-run
missinglock 里有,但本地文件丢了可重新 sql pull --sqlcode <code>
unchanged本地和 lock 一致通常无需处理
remoteOnly远端有,本地/lock 没有--remote 时检查,按需 pull

检查远端独有 SQL:

Bash
rabetbase sql status --remote --format json

9. 推送修改到平台

先预览:

Bash
rabetbase sql push --sqlcode <sqlCode> --dry-run --format json

确认后正式推送:

Bash
rabetbase sql push --sqlcode <sqlCode> --yes --format json

不传 --sqlcode 会扫描当前应用本地同步目录下所有 SQL:

Bash
rabetbase sql push --dry-run --format json

如果本地 hash 和 lock 一致但仍想强制推:

Bash
rabetbase sql push --sqlcode <sqlCode> --force --yes --format json

推送成功后,CLI 会:

  • 上传 SQL/XML 正文到平台。
  • 自动剥离本地 @lovrabet 头注释。
  • 刷新 sql.lock.json 中的 hash、路径、版本号等。

10. 执行验证

无参数执行:

Bash
rabetbase sql exec --sqlcode <sqlCode> --format json

带参数执行:

Bash
rabetbase sql exec --sqlcode <sqlCode> --params '{"status":1}' --format json

返回通常包含:

JSON
{
  "rows": [],
  "rowCount": 0,
  "elapsed": 123
}

建议:每次 push 后至少执行一次 exec,确认 SQL 参数、字段和返回结构符合调用方预期。


11. 删除 SQL

先预览:

Bash
rabetbase sql delete --sqlcode <sqlCode> --dry-run --format json

确认后删除:

Bash
rabetbase sql delete --sqlcode <sqlCode> --yes --format json

删除成功后:

  • 平台 SQL 会被删除。
  • 本地 SQL 文件会移动到 .rabetbase/sql-trash/
  • sql.lock.json 中对应条目会被移除。

删除后建议确认:

Bash
rabetbase sql list --name <sqlName> --format json
rabetbase sql status --format json

12. sql save 已废弃

旧流程里可能会看到:

Bash
rabetbase sql save --file ...

当前不要再用它作为新建或修改入口。现在迁移为:

Bash
# 新建
rabetbase sql create --name <sqlName> --db-id <dbId> --mode sql|mybatisXml --yes

# 修改
rabetbase sql push --sqlcode <sqlCode> --yes

如果执行 sql save,CLI 只会返回迁移提示,不会实际保存。


13. 推荐开发 SOP

新建 SQL:

Bash
rabetbase sql create --name getUserList --db-id 10001 --mode sql --dry-run --format json
rabetbase sql create --name getUserList --db-id 10001 --mode sql --yes --format json
rabetbase sql validate --file ./.rabetbase/sql/<appCode>/<dbName>/<sqlCode>_getUserList.sql --format json
rabetbase sql status --format json
rabetbase sql push --sqlcode <sqlCode> --dry-run --format json
rabetbase sql push --sqlcode <sqlCode> --yes --format json
rabetbase sql exec --sqlcode <sqlCode> --params '{"status":1}' --format json

修改已有 SQL:

Bash
rabetbase sql list --name getUserList --format json
rabetbase sql pull --sqlcode <sqlCode> --format json
rabetbase sql validate --file ./.rabetbase/sql/<appCode>/<dbName>/<sqlCode>_getUserList.sql --format json
rabetbase sql status --format json
rabetbase sql push --sqlcode <sqlCode> --dry-run --format json
rabetbase sql push --sqlcode <sqlCode> --yes --format json
rabetbase sql exec --sqlcode <sqlCode> --params '{"status":1}' --format json

删除 SQL:

Bash
rabetbase sql delete --sqlcode <sqlCode> --dry-run --format json
rabetbase sql delete --sqlcode <sqlCode> --yes --format json

14. 常见问题

14.1 不知道 db-id 怎么找

如果你已经知道要用哪个数据库,但不知道 ID,可以先看平台数据库配置,或者让团队在项目说明里记录常用 dbId

如果只是维护已有 SQL,优先 sql pull,CLI 会按远端 SQL 里的 dbId 生成目录。

14.2 local differs from remote

说明本地文件与远端内容不一致。先判断方向:

  • 要保留本地修改:执行 sql push --sqlcode <sqlCode> --dry-run,确认后 --yes
  • 要放弃本地修改:执行 sql pull --sqlcode <sqlCode> --force

14.3 missing remote version

说明 lock 里没有远端版本号。先执行:

Bash
rabetbase sql pull --sqlcode <sqlCode> --force --format json

再重新修改和 push

14.4 本地改了文件名会怎样

文件名中的 <sqlName> 会被视为当前 SQL 名称。只改文件名也会被 sql status 识别为 modified,执行 sql push 后会同步更新远端 SQL 名称。

14.5 换数据库目录会怎样

如果把文件从一个数据库目录移动到另一个数据库目录,sql push 会尝试按目录名重新解析目标 dbId,并同步远端绑定。目录名建议使用 CLI 生成的名称,不要随意改成无法识别的名字。

14.6 什么时候用 --force

只在明确要覆盖本地或强制重新推送时使用:

  • sql pull --force:用远端覆盖本地。
  • sql push --force --yes:即使本地 hash 看起来没变,也强制推送。

15. 总结

开发者日常只需要记住:

Plain
新建用 create,修改用本地文件 + push,拉远端用 pull,提交前先 validate 和 status,sql save 不再使用。

本地自定义 SQL 使用教程

基于飞书知识库同步生成,内容以飞书源文档为准