集腋成裘,聚沙成塔。几秒钟虽然不长,却构成永恒长河中的伟大时代。——弗莱彻
dbVisitor:用一套 Java API,打通 MySQL、MongoDB、Elasticsearch…
dbVisitor 的愿景很直接:“One API Access Any DataBase”。它是一个基于 JDBC 标准构建的统一数据访问基座,通过“API 分层 + 双层适配器架构”,把传统 RDBMS 与 NoSQL 的编程壁垒拆开重组,不用发明新语法,不遮盖差异,而是“标准化管理差异”,让你在 Java 里用同一套 API 同时玩转 MySQL、PostgreSQL、MongoDB、Elasticsearch,甚至还能把它当成 JDBC Driver,让 MyBatis/Hibernate 这类框架去操作 NoSQL。
- 官网与文档
- 仓库与简述
- GitHub: https://github.com/zycgit/dbvisitor
- 主页(英):https://www.dbvisitor.net/en/
- 许可:Apache 2.0
- 描述:JDBC-based unified data access layer,Dual-Layer Architecture,桥接 RDBMS 与 NoSQL(MySQL、MongoDB…),标准 API,无新语法
它如何统一:��层 API 的“可控抽象”
dbVisitor 不靠“魔法语法”,而是用“分层抽象”管理差异,给出从“最省心”到“最灵活”的不同层级:
-
LambdaTemplate:屏蔽差异
类型安全的链式构建器,单表 CRUD 开箱即用,自动翻译为目标数据库的 SQL 或 DSL。 -
Mapper/Interface:管理差异
声明式接口,@Query/XML 把 SQL/DSL 和代码分离;BaseMapper 提供通用方法。 -
JdbcTemplate:透传差异
标准 JDBC 模板,原生 SQL 和 Shell 透传,ConnectionCallback 直达底层驱动 API。
换言之:能否“写少点”由你决定;要不要“完全掌控”也由你决定。API 之间共享同一套底层机制,不会成为“缝合怪”。
框架特性与能力地图
- 统一基座:一套 API,同步覆盖 RDBMS 与 NoSQL
- 广泛兼容:纯 Java(JDK8+),核心仅依赖 cobble,适配 Spring/Solon 等
- 分层 API:编程式、声明式、BaseMapper、Lambda 构造器、文件 Mapper、JDBC 适配器
- 对象映射:智能结果集映射,驼峰转换、属性填充、内置 6 种主键生成器(可自定义)
Tips:不支持关系映射(1对1/1对多/多对1/多对多) - SQL 规则:
@{...}动态 SQL 规则,@{and}、@{or}、@{in}等条件增强;参数预处理(@{md5}、@{uuid}…) - 参数处理:位置参数
?、名称参数:name/&name/#{...}、注入${...}、规则传参@{...}、接口式定制 - TypeHandler:基础类型、JSON、枚举、数组、时间、GIS、流、字节等丰富类型映射
- 结果接收:Bean 映射、RowMapper、RowCallbackHandler、ResultSetExtractor 等
- 事务:多数据源事务(非分布式),7 种事务传播行为;支持编程式、注解式、模板式控制
Tips:统一了事务调用形式,不改变底层数据库物理特性 - 高阶能力:统一分页(自动适配 Limit/ROWNUM/Skip 方言)、多种集合结构返回
- 驱动适配器:可变身为独立 JDBC Driver,让 MyBatis/Hibernate 也能操作 NoSQL;已支持 Redis、MongoDB、Elasticsearch
上手三步:坐稳发车
引入依赖(以 Maven 为例,版本以 Maven Central 为准):
1 | |
统一 CRUD(同样的代码可跑 MySQL 或 Elasticsearch,自动翻译为 SQL 或 DSL):
1 | |
写接口还是写 XML?你说了算
你可以像 MyBatis 一样写 Mapper 接口,也可以全部用 Java 构造,不必纠结。
1 | |
XML 中你既可以写原生 SQL,也可以把对应 ES 的 JSON DSL 写成注释备忘,保持“同构思维”。
1 | |
逃生舱:原生直通 + Unwrap 底层驱动
当抽象不够用时,直接透传原生语句,或把 JDBC Connection 拆包成底层驱动对象,随你调用。
1 | |
这就是“统一 API + 逃生舱”的组合拳:绝大多数时候你写统一层,遇到极端需求不绕路。
和现有栈如何相处
- Spring、Spring Boot、Solon、Hasor、Guice、Main 程序都能无缝集成
- 你可以只用它的 JDBC Driver,让 MyBatis/Hibernate 直接操作 NoSQL
- 统一分页、TypeHandler 丰富、事务语义等,都在“统一基座”的逻辑中保持一致
实用小贴士
-
动态 SQL 规则
用@{...}把复杂条件写清楚,比如@{and}、@{or}、@{in}会根据参数空值自动判定是否生效。对参数的预处理(如@{md5}、@{uuid})让“入库前改造值”这类需求更优雅。 -
命名参数与注入
既支持?位置参数,也支持:name/#{...}名称参数;#{...}与${...}的区别按安全性与注入语义使用;配合规则传参更灵活。 -
关系映射
dbVisitor 不做一对一/一对多等关系映射,避免 ORM 的隐藏开销与复杂语义;更多的是“强 Map 亲和力”的结果集风格与统一分页。
兼容性与限制(JDBC Driver 层)
作为 JDBC Driver 使用时,需注意以下限制(节选):
1 | |
这些限制大多发生在“非关系型场景 + JDBC 语义”的交叉地带,属于可预期边界。
适用场景
-
多数据源统一访问层
在一个服务里同时读写 MySQL 与 Elasticsearch,不想绑死框架,不想在 ORM 与原生驱动间反复切换。 -
代码与 SQL/DSL 解耦
需要把复杂 SQL/DSL 与业务代码隔离,通过接口与 XML/文件统一管理。 -
需要“即插即用”的 NoSQL 能力
老项目基于 MyBatis/Hibernate,想以最小代价接入 Mongo/ES,走 JDBC Driver 路线。 -
有“极端诉求”的工程团队
既要统一抽象,也要保留直达底层的逃生舱,避免被高层 API 限制。
资源与下一步
- 官网与指南
- 博客文章
- 仓库
建议动手路线:
- 引入依赖,跟着“统一 CRUD + Mapper + XML”跑一个完整用例
- 挑一个 RDBMS + 一个 NoSQL,验证“同一段代码”在两端的行为一致性
- 试试动态 SQL 规则与命名参数,把常见的拼接痛点用
@{...}优雅化 - 在极端场景下走一次“原生直通 + Unwrap”,确保你的底层自由度在线
dbVisitor 的价值,不在于“完全一致”,而在于“用统一 API 管理差异”。当你的数据版图横跨多形态,工程团队又强调可控、可治理、可逃生,这套基座会让代码层次与工作流都清爽不少。