新一代 Java 数据访问库:dbVisitor
数据访问层(DAL)技术已经非常成熟,从最早的 JDBC 到 Hibernate、MyBatis,再到 Spring Data JPA。我们习惯了用这些框架处理数据。然而,当我们把目光投向“数据”本身的变化时,会发现这些经典的框架似乎正逐渐变为“老一代”。
新一代的挑战不再仅仅是如何优雅地写 SQL,而是如何用统一的方式访问那些不再仅仅存储在关系型数据库中的数据。
一、老旧的一代
谈论 “老一代” 数据访问库,并非贬义,而是指它们诞生的时代背景和核心使命。
在过去以及现在,MyBatis、Hibernate、JPA (Hibernate)、Spring JDBC Template 以及 Apache Commons DbUtils 统治了 Java 开发者的工具箱。它们的共同特征非常明显:
- 关系型数据库:它们的设计初衷就是为了更好地操作 Oracle, MySQL, PostgreSQL 等数据库。核心逻辑 无论是 ORM 映射还是 SQL 模板,都紧紧围绕着 SQL 标准。
- 专有性:当 NoSQL 兴起后,这些框架显得力不从心。于是我们看到了 MongoDB Java Driver、Elasticsearch RestHighLevelClient 等专有 SDK。
这种格局导致了一个现象:要么专有,要么偏向纯关系型数据库。如果你的应用既要查 MySQL 也要查 Elasticsearch,你通常需要引入两套完全不同的技术栈,写两套风格迥异的代码。
二、破旧尝试
数据库技术一直在不断的迭代,文档型数据库(MongoDB)、搜索引擎(Elasticsearch/OpenSearch)、键值存储(Redis)、时序数据库乃至现在的向量数据库蜂拥而至。
面对这些 “新东西”,我们熟悉的 “老配方” 也在尝试去解决新问题。于是我们看到了一系列试图弥合裂痕的动作:
- Easy-ES:试图用 MyBatis-Plus 的习惯去操作 Elasticsearch,让开发者像操作数据库表一样操作索引。
- Hibernate OGM:试图将 JPA 标准延续到 NoSQL 领域,用注解映射非关系型数据。
- Spring Data:通过统一的 Repository 接口抽象,试图掩盖底层实现的差异(如
JpaRepository与MongoRepository)。
然而,这些努力虽然在一定程度上缓解了问题,但依然难以掩盖核心的 困境:
-
套用 SQL 思维: SQL 是关系型数据库的通用语,但对于具有嵌套结构、倒排索引或图关系的数据,强行套用 SQL 或表格思维。 像 Easy-ES 这 样的工具虽然方便,但在处理 ES 特有的聚合或复杂 DSL 时,往往还是需要回退到原生 QueryDSL。
-
中间件对 JDBC 的态度: JDBC 本是 Java 届最成功的抽象之一,但它被打上了深深的关系型数据库烙印。
- Elasticsearch:曾经尝试提供 JDBC 支持,但限制诸多(不支持嵌套对象复杂查询),甚至一度计划废弃 SQL 插件。
- MongoDB:虽然有商业版的 JDBC 驱动,但社区生态中大家更习惯用 MongoTemplate 或原声 BSON API。
-
API 接口层面的持续割裂: 尽管有 Spring Data 这样的封装,但底层的割裂依然存在。
- 关系型数据库:
mapper.selectById(id) - MongoDB:
mongoTemplate.findById(id, class) - Elasticsearch:
client.get(new GetRequest(index, id))
这种割裂不仅增加了学习成本,更让架构设计变得复杂。我们看似有了一堆工具,但依然没有一个真正的 “One API” 来统一所有数据访问。
- 关系型数据库:
三、One API Access Any DataBase
既然已经走向多元化,数据访问层(DAL)也必须进化。 新一代数据访问库的使命,应当是让数据访问重新实现标准化和统一化。
我们不再应该问 “这是什么数据库?”,而应该问 “我想在这个数据源上做什么操作?”。
继承 JDBC 和 SQL 的普世精神,但打破其对关系型数据库的枷锁,这就是新一代数据访问库的目标。将其概括为 一句就是:"One API Access Any DataBase"。
四、 技术选择与可行路径
要实现这个宏大的愿景,技术上有两条主要路径可供选择:
路径 1:统一 DSL
这条路试图定义一种 “万能语言”,能同时表达关系查询、文档检索、图遍历等逻辑。
-
类似 SQL 的统一 DSL: 本质的难点在于 应用场景 的不同,导致很难有一个统一的 DSL 能在所有场景下适用。比如 Oracle、MongoDB、Elasticsearch 甚至是 Redis 在语法层面达成共识。
-
自然语言: 一种更大胆的假设,基于 LLM 大语言模型直接将自然语言解释为数据库引擎可执行的 物理执行计划,也就是:
自然语言 -> AI -> 算子树 -> 存储引擎, AI 在这一过程中充当了 Parser 和 Optimizer 的角色,直接驱动数据库内核运行具体的物理任务。但在当下,AI 在处理 语义精确性、数据访问安全性以及复杂逻辑推理 时仍存在“幻觉”风险。 将不确定的 AI 推理直接作用于确定性的数据存储内核,这将会是一场极具冒险的行为。因此,它更多被视为辅助工具(Copilot),而非底层的、确定性的数据访问标准。