02 - 核心概念
2.1 架构设计
设计理念
DLZ-DB 的核心设计理念是:极简、直观、可追踪
传统模式:
Controller → Service → ServiceImpl → Mapper → XML → DB
DLZ-DB 模式:
Controller → DB → 数据库
架构图
┌─────────────────────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ DB (统一入口) │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────── SQL Builder (SQL构建器) ────────────────┐ │
│ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐ │
│ │ Pojo │ │ Table │ │ Jdbc │ | Sql │ | Batch │ │
│ │ (实体操作) │ │(表名操作)│ │ (原生SQL) │ │ (预设 SQL)│ │ (批处理) │ │
│ └───────────┘ └───────────┘ └───────────┘ └──────────┘ └──────────┘ │
│ │ │ │
│ └────────────────────────┼──────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ SQL Logger (日志) │ │
│ │ · 完整SQL · 耗时 · 代码定位 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────┐ ┌─────────────┐ │
│ │ JDBC Template │ < -------- > │ Database │ │
│ └────────────────────────────────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 结果取值器 │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │ │
└────────────────────────────────────┼────────────────────────────────────┘
▼
┌─────────────┐
│ 应用 │
└─────────────┘
2.2 核心组件
入口
| 使用模式 | 职责 | 说明 |
|---|---|---|
| DB | 统一入口 | 所有操作的起点 |
DB(推荐)
- 快速创建多种模式执行器
- 灵活的链式操作
- 灵活的分页和排序参数
- 支持多种快捷结果查询
DB入口样例
// 查询
DB.Pojo.select(User.class) // Pojo查询(推荐)
DB.Pojo.select(user) // Pojo查询(推荐)
DB.Table.select("user") // Table查询
DB.Jdbc.select(sql, args) // 原生 SQL 查询
DB.Sql.select("key.xxx") // 预设 SQL 查询
// 插入
DB.Pojo.insert(user) // Wrapper 插入
DB.Table.insert("user") // Tabel 插入
DB.Jdbc.executer(sql, args) // 原生 SQL 插入
DB.Sql.executer("key.xxx") // 预设 SQL 插入
// 更新
DB.Pojo.update(user) // Wrapper 更新
DB.Pojo.update(User.class) // Wrapper 更新
DB.Table.update("user") // Tabel 更新
DB.Jdbc.executer(sql, args) //原生 SQL 更新
DB.Sql.executer("key.xxx") // 预设 SQL 更新
// 删除
DB.Pojo.delete(User.class) // Wrapper 删除
DB.Pojo.delete(user) // Wrapper 删除
DB.Table.delete("user") // Tabel 删除
DB.Jdbc.executer(sql, args) // 原生 SQL 删除
DB.Sql.executer("key.xxx") // 预设 SQL 删除
// 批量处理
DB.Batch.insert(List) // 批量插入
DB.Batch.update(sql, List<Object[]>)// 批量更新
5种包装器
| 构造器 | 职责 | 说明 |
|---|---|---|
| Pojo | Bean 操作 | 基于实体类的类型安全操作 |
| Table | 表名操作 | 基于表名和字段名的动态操作 |
| Jdbc | 原生 SQL | 执行原生 SQL,?传参 |
| Sql | 预设 SQL | #{key} ${key} 传参,支持条件判断 |
| Batch | 批量处理 | 批量更新和删除 |
Pojo特点:
- 支持 Lambda 表达式引用字段
- 编译期类型检查
- IDE 自动补全
Table特点:
- 不需要实体类
- 适合动态表名场景
- 字段名称支持驼峰,支持bean属性映射
- 更加灵活
Jdbc特点:
- 自定义sql, ?传参
- 适合动态生成sql
- 任意sql
Sql特点:
- sql预设(配置文件或db)
- 支持复杂sql
- 支持sql片段引入
- 支持动态条件判断
- 支持热更新
- 适合动态sql应用场景
- 任意sql
Batch特点:
- 批量执行,性能更好
数据库操作执行方法
| 取值方法 | 结果类型 | 说明 |
|---|---|---|
| queryOne | 取得单条结果 | 查询到多条时取第一条,取不到结果返回空 支持多条结果报错 |
| queryPage | 取得带翻页结果集 | 总条数和当前页结果。 总条数为0,不查询结果 |
| queryList | 查询结果集 | 结果集查询为列表 |
| count | 计算条数 | 将普通sql转换成count,取得数据条数 |
| execute | 影响条数 | 执行增加,删除,更新操作 |
其他查询结果:按需转换
| 结果类型 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| ResultMap | 继承自JSONMap | 支持多级取值,支持任意类型转换 | 字段名为字符串 |
| Bean | 指定的bean | 字段映射支持驼峰命名,自定义绑定 | 数据类型固定 |
| String | 结果中有一个字段或多个字段,取第一个 | 快捷的方式取出查询结果 | 无 |
| Long | 同上 | 同上 | 无 |
| Integer | 同上 | 同上 | 无 |
| Double | 同上 | 同上 | 无 |
2.3 更多组件说明
| 组件名称 | 结果类型 | 说明 |
|---|---|---|
| Condition | 条件构造器 | 查询到多条时取第一条,取不到结果返回空 支持多条结果报错 |
| ResultMap | 查询结果集 | 结果集查询为列表 |
| Page | 取得带翻页结果集 | 总条数和当前页结果。 总条数为0,不查询结果 |
2.3.1 Condition 条件构造器
独立的条件构造器,可复用
Condition condition = Condition.where()
.eq("status", 1)
.gt("age", 18)
.or(w -> w.eq("type", 1).eq("type", 2));
// 可以应用到不同操作
DB.Table.select("user").where(condition).queryList();
DB.Table.update("user").set("flag",1).where(condition).execute();
DB.Table.delete("user").where(condition).execute();
2.3.2. ResultMap 结果对象
查询结果,继承自 JSONMap,支持深度取值
ResultMap result = DB.Table.select("user").eq("id", 1).queryOne();
// 基础取值
result.getStr("name");
result.getInt("age",0);
// 深度取值
result.getStr("profile.address.city","未知");
result.getList("orders",Order.class);
2.3.3. Page 分页对象
封装分页参数和结果
// 创建分页参数
Page page = Page.build(1, 10); // 第1页,10条
Page page = Page.build(1, 10, Order.desc("id")); // 带排序
// 分页结果
Page<User> result = DB.Pojo.select(User.class).page(page).queryBeanPage();
List<User> records = result.getRecords(); // 数据列表
long total = result.getTotal(); // 总条数
int pages = result.getPages(); // 总页数
2.3 工作流程
查询数据流程
1. 调用 DB.Pojo.select()
↓
2. 链式添加条件 (.eq(), .like(), ...)
↓
3. 链式添加排序,分页 ( .orderBy(),.page()... )
↓
4. 构建 SQL
↓
5. 日志输出(SQL + 耗时 + 代码位置)
↓
6. 执行 JDBC
↓
7. 结果映射(Bean / Map / ResultMap)
↓
8. 返回结果
更新数据流程
1. 调用 DB.Pojo.update()
↓
2. 链式设置值 (.set(key,value), .set(Map<key,value>))
↓
3. 链式添加条件 (.eq(), .like()...)
↓
4. 构建 SQL
↓
5. 日志输出(SQL + 耗时 + 代码位置)
↓
6. 执行 JDBC
↓
7. 返回结果(影响条数)
删除数据流程
1. 调用 DB.Pojo.delete()
↓
2. 链式添加条件 (.eq(), .like()...)
↓
3. 构建 SQL
↓
4. 日志输出(SQL + 耗时 + 代码位置)
↓
5. 执行 JDBC
↓
6. 返回结果(影响条数)
新增数据流程
1. 调用 DB.Pojo.insert()
↓
2. 链式设置值 (.value(key,value), .value(Map<key,value>))
↓
3. 构建 SQL
↓
4. 日志输出(SQL + 耗时 + 代码位置)
↓
5. 执行 JDBC
↓
6. 返回结果(影响条数)
条件构建流程
DB.Pojo.select(User.class)
.eq(User::getStatus, 1) // status = 1
.gt(User::getAge, 18) // AND age > 18
.or(w -> w // AND (
.eq(User::getType, 1) // type = 1
.eq(User::getType, 2) // OR type = 2
) // )
.queryBeanList();
// 最终 SQL:
// SELECT * FROM user
// WHERE status = 1 AND age > 18 AND (type = 1 OR type = 2)
// AND is_deleted = 0
日志输出流程
DB.Pojo.select(User.class).eq(User::getId, 1).queryBeanList();
//输出日志如下:
//caller:(UserService.java:42) c.d.db.util.DbLogUtil:109 getList 15ms sql:SELECT * FROM user WHERE id = 1
┌─ SQL 执行前 ─────────────────────────────────────┐
│ 1. 获取完整 SQL(参数已填充) │
│ 2. 记录开始时间 │
└─────────────────────────────────────────────────┘
↓
┌─ SQL 执行 ──────────────────────────────────────┐
│ JDBC 执行 SQL │
└─────────────────────────────────────────────────┘
↓
┌─ SQL 执行后 ────────────────────────────────────┐
│ 1. 计算执行耗时 │
│ 2. 获取调用栈,定位业务代码 │
│ 3. 格式化输出日志 │
│ │
│ [time] 18:00:51.240 │
│ [TraceId] pJwECms9 │
│ [TheadId] main │
│ [调用] caller:(UserService.java:42) │
│ [日志输出] c.d.db.util.DbLogUtil:109 │
│ [DAO方法] getList │
│ [耗时] 15ms │
│ [SQL] SELECT * FROM user WHERE id = 1 │
└────────────────────────────────────────────────┘