11[ ![ License] ( https://img.shields.io/badge/License-Apache%202.0-blue.svg )] ( https://github.com/codingapi/dbstream-driver/blob/main/LICENSE )
2- [ ![ Maven Central] ( https://img.shields.io/maven-central/v/com.codingapi.dbstream/dbstream-driver.svg?label=Maven%20Central )] ( https://search.maven.org/search?q=g:%22com.codingapi.dbstream%22%20AND%20a:%dbstream -driver%22 )
2+ [ ![ Maven Central] ( https://img.shields.io/maven-central/v/com.codingapi.dbstream/dbstream-driver.svg?label=Maven%20Central )] ( https://search.maven.org/search?q=g:%22com.codingapi.dbstream%22%20AND%20a:%22dbstream -driver%22 )
33
44# dbstream-driver
55
6- dbstream-driver框架,是一个代理关系性数据库推送数据变更消息的代理框架。通过代理JDBC驱动实现监控数据库的持久化操作,然后将影响的数据推送出来,可用于数据宽表查询优化,统一数据统计口径,数据实时备份,数据缓存备份等场景
6+ 一个基于 JDBC 代理驱动的数据库变更事件推送框架,通过代理 JDBC 驱动实现监控数据库的持久化操作,自动捕获 INSERT/UPDATE/DELETE 操作并推送结构化数据变更事件。
77
8- ## 依赖环境
8+ ## ✨ 核心特性
99
10- * JDK 8 +
11- * Maven 3.9 +
10+ ### 🚀 无侵入性(Non-invasive)
11+ - ** 零代码修改** :无需修改任何业务代码,只需替换 JDBC 驱动类名
12+ - ** 透明代理** :自动委派给真实 JDBC 驱动,保持原有功能完全不变
13+ - ** 配置即用** :修改数据源配置即可启用,无需额外代码
1214
13- ## 快速开始(集成 dbstream-driver)
15+ ### 💡 方便性(Convenience)
16+ - ** 自动元数据扫描** :首次连接自动扫描并缓存数据库表结构、字段、主键等元数据信息
17+ - ** 内置解析器** :内置 INSERT/UPDATE/DELETE SQL 解析器,自动提取变更数据
18+ - ** 事务感知** :自动识别事务边界,支持自动提交和手动事务模式
19+ - ** 多数据源支持** :通过 jdbcKey 区分不同数据源,支持多数据源场景
1420
15- 以下以 Spring Boot 项目为例,展示最少集成步骤。
21+ ### 🔧 扩展性(Extensibility)
22+ - ** 监听器机制** :支持自定义 ` SQLExecuteListener ` 监听 SQL 执行前后事件
23+ - ** 事件推送器** :支持自定义 ` DBEventPusher ` 实现事件推送逻辑(如对接消息队列)
24+ - ** 插件化架构** :基于接口设计,易于扩展和定制
1625
17- 1 ) 引入依赖
1826
19- 在你的应用 ` pom.xml ` 中添加(确保能解析此模块依赖;若为多模块同仓库则按模块方式引用),dbstream-driver支持jdk1.8及以上的版本:
27+ ## 📋 应用场景
2028
21- ``` xml
29+ - ** 数据宽表查询优化** :实时同步数据到宽表,提升查询性能
30+ - ** 统一数据统计口径** :实时捕获数据变更,统一数据统计逻辑
31+ - ** 数据实时备份** :监听数据变更,实现实时数据备份
32+ - ** 数据缓存同步** :数据库变更时自动更新缓存
33+ - ** 数据变更审计** :记录所有数据变更操作,用于审计和追溯
34+ - ** 数据同步** :实现数据库之间的实时数据同步
35+
36+ ## 🔧 依赖环境
37+
38+ - ** JDK** : 8 +
39+ - ** Maven** : 3.8 +
40+
41+ ## 🚀 快速开始
2242
43+ ### 1. 引入依赖
44+
45+ 在项目的 ` pom.xml ` 中添加依赖:
46+
47+ ``` xml
2348<dependency >
2449 <groupId >com.codingapi.dbstream</groupId >
2550 <artifactId >dbstream-driver</artifactId >
2651 <version >${latest.version}</version >
2752</dependency >
2853```
2954
30- 2 ) 配置数据源使用代理驱动
55+ ### 2. 配置数据源
3156
32- 将数据源驱动类配置为 ` com.codingapi.dbstream.driver.DBStreamProxyDriver ` ,URL 仍使用原有 JDBC URL(示例为 MySQL):
57+ 将数据源驱动类配置为 ` com.codingapi.dbstream.driver.DBStreamProxyDriver ` ,URL 保持原有 JDBC URL 不变:
58+
59+ ** Spring Boot 配置示例(application.properties):**
3360
3461``` properties
3562spring.datasource.driver-class-name =com.codingapi.dbstream.driver.DBStreamProxyDriver
@@ -38,11 +65,40 @@ spring.datasource.username=root
3865spring.datasource.password =12345678
3966```
4067
41- 代理驱动会在运行期自动寻找并委派给真实 JDBC 驱动(通过 ` DriverManager ` 探测 URL),并在 SQL 执行前后注入拦截逻辑 。
68+ ** 说明 ** :代理驱动会在运行时自动识别 JDBC URL 并委派给真实 JDBC 驱动(如 MySQL、PostgreSQL、H2 等),无需额外配置 。
4269
43- 3 ) 订阅 SQL 执行回调 (可选)
70+ ### 3. 订阅数据库变更事件 (可选)
4471
45- 实现并注册 ` SQLExecuteListener ` ,可以拿到原始 SQL 与参数:
72+ 实现并注册 ` DBEventPusher ` 接口,接收结构化的数据库变更事件:
73+
74+ ``` java
75+ import com.codingapi.dbstream.DBStreamContext ;
76+ import com.codingapi.dbstream.stream.DBEvent ;
77+ import com.codingapi.dbstream.stream.DBEventPusher ;
78+
79+ // 在应用启动时注册事件推送器(如 @PostConstruct、@Configuration 等)
80+ DBStreamContext . getInstance(). addEventPusher(new DBEventPusher () {
81+ @Override
82+ public void push (List<DBEvent > events ) {
83+ // 处理数据库变更事件
84+ for (DBEvent event : events) {
85+ System . out. println(" 表名: " + event. getTableName());
86+ System . out. println(" 操作类型: " + event. getType()); // INSERT/UPDATE/DELETE
87+ System . out. println(" 变更数据: " + event. getData());
88+ System . out. println(" 主键: " + event. getPrimaryKeys());
89+ System . out. println(" 事务标识: " + event. getTransactionKey());
90+ System . out. println(" 时间戳: " + event. getTimestamp());
91+
92+ // 可以对接消息队列(如 Kafka、RocketMQ 等)
93+ // kafkaProducer.send(event);
94+ }
95+ }
96+ });
97+ ```
98+
99+ ### 4. 订阅 SQL 执行回调(可选)
100+
101+ 实现并注册 ` SQLExecuteListener ` ,可以获取原始 SQL 和参数信息:
46102
47103``` java
48104import com.codingapi.dbstream.DBStreamContext ;
@@ -51,62 +107,112 @@ import com.codingapi.dbstream.listener.SQLExecuteListener;
51107
52108public class MySQLListener implements SQLExecuteListener {
53109 @Override
54- public void after (SQLExecuteState executeState , Object result ) {
55- System . out. println(" after sql=" + executeState. getSql() + " , params=" + executeState. getListParams());
110+ public void before (SQLExecuteState executeState ) {
111+ System . out. println(" 执行前 - SQL: " + executeState. getSql());
112+ System . out. println(" 执行前 - 参数: " + executeState. getListParams());
56113 }
57114
58115 @Override
59- public void before (SQLExecuteState executeState ) {
60- System . out. println(" before sql=" + executeState. getSql() + " , params=" + executeState. getListParams());
116+ public void after (SQLExecuteState executeState , Object result ) {
117+ System . out. println(" 执行后 - SQL: " + executeState. getSql());
118+ System . out. println(" 执行后 - 参数: " + executeState. getListParams());
119+ System . out. println(" 执行后 - 结果: " + result);
61120 }
62121}
63122
64- // 在应用启动后注册(例如 @PostConstruct、测试用 @BeforeEach 等)
123+ // 注册监听器
65124DBStreamContext . getInstance(). addListener(new MySQLListener ());
66125```
67126
68- 4 ) 订阅数据库事件推送(INSERT/UPDATE/DELETE 的行级事件)
127+ ## 📖 API 文档
128+
129+ ### DBStreamContext
130+
131+ 框架的核心上下文类,提供所有对外能力:
132+
133+ #### 事件推送相关
134+
135+ ``` java
136+ // 添加数据库事件推送器
137+ DBStreamContext . getInstance(). addEventPusher(DBEventPusher pusher);
138+ ```
139+
140+ #### 监听器相关
141+
142+ ``` java
143+ // 添加 SQL 执行监听器
144+ DBStreamContext . getInstance(). addListener(SQLExecuteListener listener);
145+ ```
69146
70- 实现并注册 ` DBEventPusher ` 接口,即可收到解析后的结构化事件 ` DBEvent ` 列表:
147+ #### 元数据管理
71148
72149``` java
73- import com.codingapi.dbstream.DBStreamContext ;
74- import com.codingapi.dbstream.stream.DBEvent ;
75- import com.codingapi.dbstream.stream.DBEventPusher ;
150+ // 获取所有数据库的元数据信息列表
151+ List<DBMetaData > metaDataList = DBStreamContext . getInstance(). metaDataList();
76152
77- DBStreamContext . getInstance(). addEventPusher(new DBEventPusher () {
78- @Override
79- public void push (List<DBEvent > events ) {
80- System . out. println(events);
81- }
82- });
153+ // 通过 jdbcKey 获取指定数据库的元数据信息
154+ DBMetaData metaData = DBStreamContext . getInstance(). getMetaData(String jdbcKey);
155+
156+ // 获取所有已缓存的数据库连接 jdbcKey 列表
157+ List<String > dbKeys = DBStreamContext . getInstance(). loadDbKeys();
158+
159+ // 清理指定数据库的元数据缓存(清空后下次访问会自动重新加载)
160+ DBStreamContext . getInstance(). clear(String jdbcKey);
161+
162+ // 清理所有数据库的元数据缓存
163+ DBStreamContext . getInstance(). clearAll();
83164```
84165
85- 事件模型包含表名、变更类型、主键、列数据、数据产生时间戳以及 JDBC URL 等信息,便于对接消息中间件或下游处理逻辑。
166+ ### DBEvent 事件模型
167+
168+ 数据库变更事件包含以下信息:
86169
87- ## 运行示例
170+ - ` tableName ` : 表名
171+ - ` type ` : 操作类型(INSERT/UPDATE/DELETE)
172+ - ` data ` : 变更的数据(Map 格式,key 为字段名,value 为字段值)
173+ - ` primaryKeys ` : 主键列表
174+ - ` jdbcUrl ` : 数据库连接 URL
175+ - ` transactionKey ` : 事务标识(同一事务内的操作共享相同标识)
176+ - ` timestamp ` : 事件产生时间戳
177+ - ` pushTimestamp ` : 事件推送时间戳
88178
89- 示例模块已集成上述配置,直接运行:
179+ ## 🧪 运行测试
180+
181+ 项目已包含完整的单元测试示例,运行测试:
90182
91183``` bash
92184mvn clean test -P travis
93185```
94186
95- ## API 速览(与集成相关)
187+ ## ⚠️ 注意事项
188+
189+ 1 . ** 事件推送时机** :
190+ - 仅在使用 ` Statement ` /` PreparedStatement ` 执行 INSERT/UPDATE/DELETE 操作时才会产生事件
191+ - SELECT 查询操作不会推送事件
192+ - 事件推送是同步触发回调,请在实现中避免耗时阻塞,必要时交给异步处理
193+
194+ 2 . ** 事务支持** :
195+ - 框架自动识别事务边界,支持自动提交和手动事务模式
196+ - 手动事务模式下,事件会在 ` commit() ` 时批量推送
197+ - 事务回滚时,相关事件会被丢弃
198+
199+ 3 . ** SQL 限制** :
200+ - 由于 JDBC 在执行 ` INSERT INTO ... SELECT ` 语句时无法获取自增 ID,框架暂不支持此类插入方式
201+ - 请避免使用 ` INSERT INTO ... SELECT ` 语句
202+
203+ 4 . ** 元数据缓存** :
204+ - 数据库元数据会在首次连接时自动扫描并缓存
205+ - 如果数据库表结构发生变化,可以调用 ` clear() ` 方法清理缓存,下次访问时会自动重新加载
206+
207+ ## 📄 许可证
96208
97- - ` DBStreamContext.getInstance().addListener(SQLExecuteListener listener) ` : 订阅 SQL 执行回调。
98- - ` DBStreamContext.getInstance().addEventPusher(DBEventPusher pusher) ` : 订阅结构化数据库事件。
99- - ` DBStreamContext.getInstance().metaDataList() ` : 获取已缓存的数据库元数据信息列表。
100- - ` DBStreamContext.getInstance().getMetaData(String jdbcKey) ` : 通过jdbcKey获取已缓存的数据库元数据信息列表。
101- - ` DBStreamContext.getInstance().loadDbKeys() ` : 获取已缓存的数据库连接jdbcKey信息。
102- - ` DBStreamContext.getInstance().clear(String jdbcKey) ` : 清理指定/全部数据库的元数据缓存,数据清空以后下次执行数据库访问时会自己重新加载元数据。
209+ 本项目采用 [ Apache License 2.0] ( ./LICENSE ) 许可证。
103210
104- ## 说明
211+ ## 🤝 贡献
105212
106- - 代理驱动默认内置针对 INSERT/UPDATE/DELETE 的解析与事件推送(见 ` SQLInsertExecuteListener ` 、` SQLUpdateExecuteListener ` 、
107- ` SQLDeleteExecuteListener ` )。
108- - 仅在使用 ` Statement ` /` PreparedStatement ` 执行写操作时才会产出事件;查询不会推送事件。
109- - 事件推送是同步触发回调,请在实现中避免耗时阻塞,必要时交给异步处理。
110- - 由于JDBC在执行insert into select语句时无法获取到自增的id,因此框架为对次插入方式进行支持,请在实现中避免这样的写法。
213+ 欢迎提交 Issue 和 Pull Request!
111214
215+ ## 📞 联系方式
112216
217+ - 项目地址: https://github.com/codingapi/dbstream-driver
218+ - 问题反馈: https://github.com/codingapi/dbstream-driver/issues
0 commit comments