让 TDengine 在 JetBrains IDEs 里更像“原生数据库”一点

小T

2026-03-25 /

作者 | ChangJin Wei(魏昌进)

小T导读:本文是一篇来自 TDengine 社区的原创投稿。作者基于自身在 JetBrains IDEs 中使用 TDengine 的实际需求,独立开发并开源了相关插件,用于增强 TDengine 在 JetBrains 数据库工具链中的接入与 SQL 开发体验。我们很高兴看到,越来越多开发者正在从真实需求出发,为 TDengine 生态带来更丰富、更实用的补充。今天将这篇文章分享给大家,也期待更多来自社区的实践与声音。

最近我做了一个小插件,把 TDengine 接入到了 JetBrains IDEs 的数据库工具链里。

先埋个小提示:文末有彩蛋。

项目地址:

• GitHub:https://github.com/galaxy-sea/TDengine-Driver-Integration

• JetBrains Plugin Marketplace:https://plugins.jetbrains.com/plugin/30538-tdengine-driver-integration

写这个插件的起因其实很直接。

我平时更习惯在 JetBrains IDEs 里处理数据库相关工作,尤其是 DataGrip 这一套交互逻辑已经用顺手了。对于 MySQL、PostgreSQL、ClickHouse 这类 JetBrains 已经支持得比较完整的数据库,连库、写 SQL、看对象定义、做补全,整个过程都比较流畅。但一旦切到 TDengine,体验就会突然断层。

不是说不能用,而是“不顺”。要么是驱动和连接参数要自己折腾,要么是 SQL 编辑体验不完整;再加上其他数据库管理工具的交互逻辑和 JetBrains IDEs 并不完全一样,来回切换时总会有一种“工具在迁就数据库,而不是数据库融入工具”的感觉。

所以我当时的想法很简单:能不能让 TDengine 在 JetBrains IDEs 里,至少先拥有接近原生数据库的基础体验?

一开始,真正难的不是写代码

真正开始动手以后,我很快发现,最难的部分并不是“把功能写出来”,而是“搞清楚应该怎么写”。

原因主要有两个。

第一,JetBrains Database 插件开发资料很少。常规 IntelliJ Platform 插件还能找到不少示例和文章,但一旦具体到 database 模块、数据源注册、元数据包装、方言挂载这些问题,能参考的内容就明显少很多。很多时候只能对着现象试、对着 API 猜,或者直接进源码里一点点摸。

第二,关于 PSI 方言设计的资料也不多。尤其是 TDengine 这种并不是完全照搬某个主流数据库方言的场景,语法该怎么拆、哪些 token 应该视为关键字、哪些应该进入函数调用链路,这些都需要自己整理。

换句话说,真正的门槛不是“插件开发”,而是“在缺少现成路径的情况下,把这套东西自己走通”。

中间最卡的三个问题

如果要总结这次开发过程中最卡的三个问题,我会归纳成下面这三个。

1. TDengine 方言的 PSI 设计

这是最核心、也最容易反复返工的一块。

JetBrains 的 SQL 能力很多都建立在 PSI 结构之上。语法树设计得不稳,后面的补全、高亮、参数提示、文档提示,基本都会跟着变形。看起来像是“只是一个函数没高亮”,本质上往往是语法分类错了。

比如 TDengine 里有些内容既像关键字又像函数,有些写法既支持裸写也支持带括号调用。如果一开始 PSI 设计没把这类情况理顺,后续处理会非常痛苦。

这部分我花了不少时间反复调整,因为它不是单点功能,而是整条链路的地基。

2. TDengine 方言的整理和归纳

写方言不是简单把关键字表贴进去就结束了。

真正麻烦的是整理规则:哪些属于关键字,哪些属于内建函数,哪些是特殊语法,哪些虽然看起来像函数但又不完全适合按普通函数处理。只要归类模糊,最后表现出来就会是补全不一致、高亮不一致、某些语句能过某些语句不能过。

这个过程更像是在做“方言工程化整理”,而不是单纯写解析器。尤其当你想把体验做成“像 JetBrains 原生支持的数据库一样”时,对一致性的要求会更高。

3. TDengine 方言的回归测试

这个问题一开始其实容易被低估。

方言适配最怕的不是“有 bug”,而是“你修了一个点,又把另一个点带坏了”。今天修了函数高亮,明天可能影响补全;今天让一种写法能过解析,明天可能把另一种写法冲掉。

而 TDengine 的语法适配又涉及 lexer、parser、PSI、completion、documentation、live templates 这些不同层次,回归验证的成本不低。很多时候不是写完就行,而是你得想清楚这次改动到底影响了哪一层。

这也让我更明确了一件事:方言适配不能只追求“先能用”,还得尽量控制后续回退成本。

最后做成了什么

到目前为止,这个插件优先完成的是两件事:连接体验和 SQL 开发体验。

在连接层面,插件提供了 TDengine 数据源入口、内置 JDBC 版本列表、连接参数模板和配置校验。也就是说,用户在 JetBrains IDEs 里添加 TDengine 数据源时,不需要再从零开始拼接配置,整体路径会更接近 JetBrains 已支持数据库的使用方式。

在 SQL 开发层面,目前已经完成了 TDengine 方言的基础适配,包括:

• TDengine 数据源接入

• JDBC 驱动版本选择与下载

• 连接配置校验

• SQL 方言支持

• 关键字补全

• 函数补全

• 函数高亮

• 函数参数提示

• 函数悬停文档

• Live Templates

对我来说,这里面最重要的不是某一个单独功能,而是整体交互逻辑终于开始“像一门被 JetBrains IDEs 认真支持的数据库”了。

这也是我最想做成的效果:当你在 JetBrains IDEs 里操作 TDengine 时,不再明显感觉自己在使用一套“勉强接上去”的能力,而是尽量贴近已经熟悉的数据库工作流。

还有哪些没做完

目前优先完成的是连接与 SQL 开发体验,GUI DDL 适配仍在推进中。

更直接一点说,现在主要还是把“写 SQL、连库、看提示”这条主链路先打通了;至于 GUI 侧的表创建、字段修改这类能力,还没有完全做完。

这部分之所以还在推进中,不是因为价值低,而是因为它和数据库工具内部的数据模型、元数据行为绑定得更深,处理起来比表面看上去复杂得多。后续如果继续迭代,我也会优先把这些 GUI 操作补齐。

为什么我觉得这件事值得做

我一直觉得,一个数据库生态是否成熟,不只取决于服务端和驱动本身,也取决于它能不能自然地进入开发者已经习惯的工作环境。

很多时候,开发者并不是缺一个“能连接 TDengine 的工具”,而是缺一个“能让 TDengine 融入现有工作流的工具”。如果一门数据库在常见 IDE 里始终缺少顺手的支持,那它在很多场景里就会天然增加使用门槛。

这个插件现在当然还谈不上完美,但至少它在一个很具体的问题上往前走了一步:让 TDengine 在 JetBrains IDEs 里,开始变得更自然一些。

如果这篇文章能让更多 TDengine 用户少走一点弯路,或者让更多开发者愿意一起补齐 JetBrains 生态里的 TDengine 支持,我觉得这件事就已经很值得了。

最后的彩蛋

对多语言开发场景来说,这次还有一个额外收益。

如果你的项目本身就在 JetBrains IDEs 里使用 MyBatis 相关插件,那么在 XML 中编写 TDengine SQL 时,也可以联动获得语法提示体验。换句话说,Java MyBatis 生态的兄弟们也有福了,XML 里的 TDengine SQL 不再只能“盲写”。

更进一步说,这个收益也不局限于 MyBatis、Java,甚至不局限于某一个固定框架。只要所在语言或框架支持 JetBrains IDEs 的语言注入能力,例如 @Language("SQL")//language=SQL 或类似机制,就可以把字符串里的 TDengine SQL 交给 IDE 识别,从而获得接近的补全和提示体验。

这不是一个单独做出来的“宣传点”,而是 TDengine 方言能力接入 JetBrains IDEs 之后,自然带出来的一个实用效果。对日常维护 XML SQL 或嵌入式 SQL 的项目来说,这一点会非常省心。