跳到主要内容

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种包装器

构造器职责说明
PojoBean 操作基于实体类的类型安全操作
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 │
└────────────────────────────────────────────────┘