跳到主要内容

6.3 框架源码指南

本文档面向需要维护、修改或扩展 DLZ-DB 框架的开发者

目录


一、项目概览

1.1 代码规模

DLZ-DB 是一个轻量级的数据库操作框架,代码规模精简:

  • 核心模块(dlz-db-core):约 10000 行生产代码
  • Spring Boot Starter:约 200 行适配代码
  • Solon Plugin:约 300 行适配代码
  • 测试用例:约 10000+ 行

1.2 设计理念

DLZ-DB 的设计理念是"不做你不需要的事":

  • 不做 Mapper 接口和 XML 双向映射 → 省掉解析引擎
  • 不做 SqlSession / Executor 分层 → 调用栈直通 JDBC
  • 不做一二级缓存 → 交给 Redis / Caffeine,各司其职

1.3 v7 架构变化

v7.0 从单模块重构为多模块架构:

dlz-db/ (父 POM, v7.0.0)
├── dlz-db-core/ (核心模块,零 Spring 依赖)
├── dlz-db-spring-boot-starter/ (Spring Boot 适配)
└── dlz-db-solon-plugin/ (Solon 适配)

核心模块不再依赖 Spring,通过接口抽象隔离框架适配层。

1.4 技术栈

  • JDK:8+
  • 构建工具:Maven
  • 数据库支持:MySQL、PostgreSQL、Oracle、达梦、SQLite
  • Spring Boot:2.x+(通过 spring-boot-starter)
  • Solon:3.x+(通过 solon-plugin)

二、代码结构

2.1 整体目录结构

dlz-db/ (父 POM)
├── pom.xml
├── dlz-db-core/ (核心模块)
│ └── src/main/java/com/dlz/db/
│ ├── annotation/ # 注解定义
│ │ ├── TableName.java
│ │ ├── TableField.java
│ │ ├── TableId.java
│ │ └── proxy/ # MyBatis-Plus 注解兼容代理
│ ├── core/ # 核心抽象接口(v7 新增)
│ │ ├── ISqlExecutor.java # SQL 执行器接口
│ │ ├── ITxExecutor.java # 事务执行器接口
│ │ ├── ICacheExecutor.java # 缓存执行器接口
│ │ ├── IRowMapper.java # 结果行映射接口(自研)
│ │ ├── ADbProvider.java # DB 提供者抽象类
│ │ ├── BaseDbProperties.java # 基础配置属性
│ │ ├── JdbcValueUtils.java # JDBC 值工具(替代 Spring JdbcUtils)
│ │ ├── ResourceMatcher.java # 资源路径匹配器
│ │ └── abstractor/ # 适配器骨架类
│ ├── modal/ # 统一入口和包装器
│ │ ├── DB.java # 统一入口类
│ │ ├── condition/Condition.java # 条件构造器
│ │ ├── dto/ # 数据传输对象
│ │ │ ├── Page.java
│ │ │ ├── Order.java
│ │ │ └── ResultMap.java
│ │ ├── para/ # 参数处理
│ │ └── wrapper/ # 查询包装器
│ ├── helper/ # SQL 构建器和自动建表
│ │ ├── SqlHelper.java # SQL 构建器
│ │ └── support/ # 自动建表 + 方言支持
│ ├── ds/ # 数据源管理
│ │ ├── DBDynamic.java # 动态数据源切换
│ │ ├── DBTx.java # 编程式事务
│ │ ├── DataSourceProperty.java # 数据源配置属性
│ │ └── DataSourceCreatorHikari.java
│ ├── holder/ # 运行时持有者
│ │ ├── DBHolder.java
│ │ ├── SqlHolder.java
│ │ └── BeanInfoHolder.java
│ ├── service/ # 通用服务接口
│ ├── convertor/ # 类型转换
│ ├── enums/ # 枚举定义
│ ├── exception/ # 异常定义
│ ├── inf/ # 内部接口
│ └── util/ # 工具类

├── dlz-db-spring-boot-starter/ (Spring Boot 适配)
│ └── src/main/java/com/dlz/db/spring/
│ ├── config/
│ │ ├── DlzDbConfig.java # Spring Boot 自动配置
│ │ ├── DlzDbProperties.java # yml 配置绑定
│ │ ├── SpringDbProvider.java # Spring 版 DBProvider
│ │ └── DynamicJdbcTemplate.java # 动态数据源 JdbcTemplate
│ ├── SpringSqlExecutorAdapter.java # SqlExecutor Spring 实现
│ ├── SpringTxExecutorAdapter.java # TxExecutor Spring 实现
│ └── SpringCacheAdapter.java # CacheExecutor Spring 实现

└── dlz-db-solon-plugin/ (Solon 适配)
└── src/main/java/com/dlz/db/solon/
├── XPluginImp.java # Solon SPI 插件入口
├── SolonDbProperties.java # Solon 配置绑定
├── SolonDbProvider.java # Solon 版 DBProvider
├── SolonSqlExecutorAdapter.java # SqlExecutor Solon 实现
├── SolonTxExecutorAdapter.java # TxExecutor Solon 实现
├── SolonConnectionHolder.java # 自研连接持有器
└── SolonJedisCacheAdapter.java # CacheExecutor Solon 实现

2.2 v7 相比 v6 的关键变化

变化说明
删除了 dao/IDlzDao/DlzDaoISqlExecutor 接口替代
新增 core/核心抽象接口,框架无关
自研 RowMapper不再依赖 Spring 的 RowMapper
自研 JdbcValueUtils替代 Spring JdbcUtils.getResultSetValue()
包名重构Spring 适配类统一移到 com.dlz.db.spring.*

三、核心模块说明

3.1 modal 包 — 统一入口与包装器

DB.java

统一入口类,提供静态方法访问所有功能:

DB.Pojo // 基于 Bean 的 CRUD
DB.Table // 基于表名的操作
DB.Jdbc // 原生 SQL 操作
DB.Sql // 预设 SQL 操作
DB.Batch // 批量操作
DB.Dynamic // 动态数据源切换

DB 类本身不依赖任何框架,通过 DBHolder 获取实际执行器实例。

condition/Condition.java

条件构造器,支持链式调用。核心设计:

  • 每个条件方法(eq/gt/like 等)返回 this 实现链式
  • lambda 嵌套(or/and)通过 Consumer<Condition> 实现
  • 三参重载实现条件判断(eq(boolean, field, value)

wrapper 包

查询包装器,共 14 个类。职责分层:

DB.Pojo → PojoQuery / PojoUpdate / PojoDelete / PojoInsert
DB.Table → TableQuery / TableUpdate / TableDelete / TableInsert
DB.Jdbc → JdbcQuery / JdbcExecute / JdbcInsert
DB.Sql → SqlQuery / SqlExecute

每个包装器最终调用 ISqlExecutor 接口执行 SQL。

3.2 helper 包 — SQL 构建器

SqlHelper.java

核心 SQL 构建引擎,负责:

  • 将条件构造器(Condition)转换为 SQL WHERE 子句
  • 支持多方言(MySQL / PostgreSQL / Oracle / 达梦 / SQLite)
  • 支持空值自动忽略(方括号语法)
  • 支持预设 SQL 参数替换(#{key}
  • 支持 SQL 嵌套引用(#{key.xxx}

support 包

自动建表和数据库方言支持:

  • DbOpMysql / DbOpPostgresql / DbOpDm8 / DbOpSqlite
  • HelperScan:注解扫描 + 自动建表
  • SqlHelper:多方言 SQL 构建

3.3 ds 包 — 数据源管理

DBDynamic.java

动态数据源切换,通过 ThreadLocal 实现:

// 核心机制:在 lambda 执行前将数据源名压入栈
DB.Dynamic.use("slave", () -> {
// 此作用域内所有操作使用 slave 数据源
DB.Pojo.select(User.class).queryList();
});

DBTx.java

编程式事务,底层委托给 ITxExecutor

DB.Tx.run(() -> {
// 此作用域内所有操作在一个事务中
});
  • Spring 环境:委托 Spring TransactionSynchronizationManager
  • Solon 环境:委托自研 ConnectionHolder(PROPAGATION_REQUIRED 语义)

3.4 holder 包 — 运行时持有者

DBHolder.java

全局持有者,保存框架运行时实例:

public class DBHolder {
public static ISqlExecutor sqlExecutor; // SQL 执行器
public static ADbProvider dbProvider; // DB 提供者
// ...
}

各模块适配层在启动时向 DBHolder 注册实现,DB 静态方法通过 DBHolder 获取实现类。


四、核心抽象接口

v7 引入的核心抽象,位于 com.dlz.db.core 包:

ISqlExecutor

SQL 执行器接口,涵盖所有 JDBC 操作:

public interface ISqlExecutor {
<T> List<T> queryList(String sql, Object[] args, RowMapper<T> mapper);
int update(String sql, Object[] args);
int insert(String sql, Object[] args, String autoKeyCol);
void execute(String sql, Object[] args);
long queryCount(String sql, Object[] args);
// ... 其他方法
}

ITxExecutor

事务执行器接口:

public interface ITxExecutor {
<T> T run(Supplier<T> supplier);
void run(Runnable runnable);
}

ICacheExecutor

缓存执行器接口:

public interface ICacheExecutor {
<T> T get(String key, Class<T> type);
void set(String key, Object value, int expireSeconds);
void del(String key);
}

IRowMapper

结果行映射接口(替代 Spring RowMapper):

public interface IRowMapper<T> {
T mapRow(ResultSet rs, int rowNum);
}

五、Spring Boot Starter

位于 dlz-db-spring-boot-starter,实现 ISqlExecutor 等接口:

接口Spring 实现底层机制
ISqlExecutorSpringSqlExecutorAdapterSpring JdbcTemplate
ITxExecutorSpringTxExecutorAdapterSpring TransactionSynchronizationManager
ICacheExecutorSpringCacheAdapterdlz-spring 的 JedisExecutor

自动装配入口:DlzDbConfig.java(用 @Bean 注册各组件)。


六、Solon Plugin

位于 dlz-db-solon-plugin,通过 Solon SPI 自动加载:

接口Solon 实现底层机制
ISqlExecutorSolonSqlExecutorAdapter自研 SimpleJdbc(基于 PreparedStatement
ITxExecutorSolonTxExecutorAdapter自研 SolonConnectionHolder(REQUIRED 语义)
ICacheExecutorSolonJedisCacheAdapterJedis 直接调用

插件入口:XPluginImp.java,通过 META-INF/solon/dlz-db-solon-plugin.properties 注册。

启动流程:

  1. 绑定 dlz.db 配置 → SolonDbProperties
  2. 注册 SolonDbProviderDBHolder
  3. 异步等待 DataSource 就绪后初始化 SqlExecutor
  4. 加载预设 SQL
  5. 若存在 JedisPool,自动注册缓存

七、开发环境搭建

7.1 克隆项目

git clone https://github.com/your-repo/dlz.db.git
cd dlz.db

7.2 构建项目

# 编译所有模块
mvn clean install -DskipTests

7.3 配置测试数据库

Spring Boot 测试配置在 dlz-db-spring-boot-starter/src/test/resources/application.yml

spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456

Solon 测试使用 SQLite(无需外部数据库),配置在 dlz-db-solon-plugin/src/test/resources/app.yml

7.4 运行测试

# 运行所有模块测试
mvn test

# 运行特定模块测试
mvn test -pl dlz-db-core
mvn test -pl dlz-db-spring-boot-starter
mvn test -pl dlz-db-solon-plugin

7.5 导入 IDE

推荐使用 IntelliJ IDEA:

  1. File → Open → 选择项目根目录
  2. 等待 Maven 依赖下载完成
  3. 运行测试用例验证环境

八、修改指南

8.1 上手时间

任务预计时间说明
熟悉 API 使用半天了解 DB.Pojo、DB.Table 等基本用法
看懂 wrapper 构建逻辑1-2 天理解条件构造器的实现原理
修改底层功能2-3 天修改 SQL 构建器、类型转换器等核心模块

8.2 常见修改场景

场景1:添加新的数据库方言支持

  1. helper/support/dbs/ 下创建新的方言类(如 DbOpOracle.java
  2. 实现方言特定的 SQL 语法(分页、数据类型等)
  3. SqlHelper 中注册方言

场景2:添加新的条件方法

  1. inf/ 包中找到对应接口添加方法签名
  2. Condition.java 中实现链式调用
  3. SqlHelper.java 中实现 SQL 生成逻辑
  4. 编写测试用例验证

场景3:添加新的框架适配

  1. core/ 包中检查是否需要新增接口
  2. 在新的 adapter 模块中实现接口
  3. 在适配模块启动时注册到 DBHolder

8.3 代码规范

  • 命名规范:遵循 Java 命名规范
  • 测试覆盖:新增功能必须编写测试用例
  • 核心模块:不得引入任何框架依赖(Spring / Solon 等)

九、测试指南

9.1 测试结构

Spring Boot 测试在 dlz-db-spring-boot-starter 模块:

dlz-db-spring-boot-starter/src/test/java/
└── com/dlz/test/db/
├── cases/db/ # 数据库操作测试
├── config/ # 测试配置
└── entity/ # 测试实体

Solon 测试在 dlz-db-solon-plugin 模块(使用 SQLite 内存数据库):

dlz-db-solon-plugin/src/test/java/
└── com/dlz/test/db/
├── cases/db/ # 数据库操作测试
├── config/ # 测试配置
└── entity/ # 测试实体

9.2 运行测试

# 运行所有测试
mvn test

# 运行特定测试类
mvn test -Dtest=PojoQueryTest

# 运行特定模块测试
mvn test -pl dlz-db-spring-boot-starter

9.3 编写测试用例

@Test
public void testSelect() {
// 准备数据
User user = new User();
user.setName("张三");
DB.Pojo.insert(user);

// 执行测试
User result = DB.Pojo.select(User.class)
.eq(User::getId, user.getId())
.queryBean();

// 验证结果
assertNotNull(result);
assertEquals("张三", result.getName());

// 清理数据
DB.Pojo.delete(User.class).eq(User::getId, user.getId()).execute();
}

十、发布流程

10.1 版本号规范

遵循语义化版本规范:主版本号.次版本号.修订号

  • 主版本号:不兼容的 API 修改
  • 次版本号:向下兼容的功能性新增
  • 修订号:向下兼容的问题修正

10.2 发布步骤

  1. 更新版本号:修改 pom.xml 中的版本号
  2. 更新文档:更新 CHANGELOG 和相关文档
  3. 运行测试:确保所有模块测试通过
  4. 提交代码:提交到主分支
  5. 打标签:创建 Git 标签
  6. 发布到 Maven 仓库

10.3 注意事项

  • v7 发布三个 artifact:dlz-db-coredlz-db-spring-boot-starterdlz-db-solon-plugin
  • 版本号必须保持一致(统一为 7.0.x)
  • 确保 core 模块的 mvn dependency:tree 不出现 org.springframework.*