06 - 结果映射
6.1 Bean 映射
自动映射规则
DLZ-DB 自动将数据库字段映射到 Bean 属性:
| 数据库字段 | Bean 属性 | 说明 |
|---|---|---|
user_name | userName | 下划线转驼峰 |
USER_NAME | userName | 大写下划线转驼峰 |
username | username | 直接匹配 |
定义实体类
@Data
@Table("sys_user") // 指定表名(可选)
public class User {
private Long id;
private String userName; // 对应 user_name
private Integer age;
@Column("email_address") // 指定列名
private String email;
private Date createTime; // 对应 create_time
@Ignore // 忽略此字段,不映射
private String tempData;
}
查询映射
// 单条映射
User user = DB.Pojo.select(User.class)
.eq(User::getId, 1)
.queryBean();
// 列表映射
List<User> users = DB.Pojo.select(User.class)
.eq(User::getStatus, 1)
.queryBeanList();
// 原生 SQL 映射
User user = DB.Jdbc.select("SELECT * FROM user WHERE id = ?", 1)
.queryOne(User.class);
// 列表映射
List<User> users = DB.Jdbc.select("SELECT * FROM user WHERE status = ?", 1)
.queryList(User.class);
复杂类型映射
@Data
public class UserDTO {
private Long id;
private String name;
// 嵌套对象(假设查询结果有 dept_id, dept_name)
private Department dept;
// JSON 字段自动解析
private List<String> tags;
// Map 类型
private Map<String, Object> extra;
}
// 查询时自动映射
UserDTO dto = DB.Jdbc.select("""
SELECT u.*, d.id as dept_id, d.name as dept_name
FROM user u
LEFT JOIN department d ON u.dept_id = d.id
WHERE u.id = ?
""", 1).queryOne(UserDTO.class);
6.2 Map 映射
ResultMap
DLZ-DB 的查询结果默认返回
ResultMap,它继承自JSONMap,具有强大的取值能力。
// 查询返回 ResultMap
ResultMap result = DB.Table.select("user")
.eq("id", 1)
.queryOne();
// 基础取值
Long id = result.getLong("id");
String name = result.getStr("name");
Integer age = result.getInt("age", 0); // 带默认值
Date createTime = result.getDate("create_time");
列表查询
// 返回 ResultMap 列表
List<ResultMap> list = DB.Table.select("user")
.eq("status", 1)
.queryList();
// 遍历处理
for (ResultMap item : list) {
String name = item.getStr("name");
Integer age = item.getInt("age");
}
// 转换为 Bean 列表
List<User> users = list.stream()
.map(m -> m.toBean(User.class))
.collect(Collectors.toList());
不需要定义实体类的场景
// 报表统计:不需要为每个报表定义 DTO
ResultMap stats = DB.Jdbc.select("""
SELECT
COUNT(*) as total,
SUM(amount) as total_amount,
AVG(amount) as avg_amount,
MAX(amount) as max_amount
FROM orders
WHERE create_time >= ?
""", startDate).queryOne();
long total = stats.getLong("total");
BigDecimal totalAmount = stats.getBigDecimal("total_amount");
BigDecimal avgAmount = stats.getBigDecimal("avg_amount");
6.3 ResultMap 深度取值
核心能力
ResultMap 继承自 JSONMap,支持:
- 深度路径取值:
a.b.c[0].d - 负数索引:
list[-1]获取最后一个元素 - 智能类型转换:自动转换为目标类型
- 空值安全:中间任意节点为空不会报错
- 嵌套 JSON 字符串解析:自动解析
深度取值
ResultMap result = DB.Jdbc.select("SELECT * FROM user WHERE id = 1").queryOne();
// 假设返回的数据结构:
// {
// "id": 1,
// "name": "张三",
// "profile": {
// "address": {
// "city": "北京",
// "district": "朝阳区"
// },
// "tags": ["开发者", "架构师", "DBA"]
// },
// "orders": [
// {"id": 101, "amount": 100},
// {"id": 102, "amount": 200}
// ]
// }
// 深度取值
String city = result.getStr("profile.address.city"); // "北京"
String district = result.getStr("profile.address.district"); // "朝阳区"
// 数组取值
String firstTag = result.getStr("profile.tags[0]"); // "开发者"
String lastTag = result.getStr("profile.tags[-1]"); // "DBA"(负数索引)
// 嵌套对象取值
Long orderId = result.getLong("orders[0].id"); // 101
BigDecimal amount = result.getBigDecimal("orders[-1].amount"); // 200
默认值
// 路径不存在时返回默认值,不会报空指针
String city = result.getStr("profile.address.city", "未知");
Integer score = result.getInt("score", 0);
List<String> tags = result.getList("profile.tags", String.class, Collections.emptyList());
类型转换
// 自动类型转换
Integer age = result.getInt("age"); // 数字 → Integer
Long id = result.getLong("id"); // 数字 → Long
Double score = result.getDouble("score"); // 数字 → Double
BigDecimal amount = result.getBigDecimal("amount");
Boolean active = result.getBoolean("active"); // 支持 true/false, 1/0, "true"/"false"
Date createTime = result.getDate("create_time");
// 获取嵌套对象
ResultMap profile = result.getMap("profile");
ResultMap address = result.getMap("profile.address");
// 获取列表
List<String> tags = result.getList("profile.tags", String.class);
List<Order> orders = result.getList("orders", Order.class);
// 转换为 Bean
User user = result.toBean(User.class);
Address addr = result.getBean("profile.address", Address.class);
嵌套 JSON 字符串
// 假设 config 字段存储的是 JSON 字符串:
// {"theme": "dark", "language": "zh"}
// 传统方式需要先解析字符串
String configStr = result.getStr("config");
JSONObject config = JSON.parseObject(configStr);
String theme = config.getString("theme");
// ResultMap 自动解析
String theme = result.getStr("config.theme"); // 直接获取
ResultMap config = result.getMap("config"); // 获取为 Map
与 ValUtil 配合
ResultMap result = ...;
// 获取原始值
Object raw = result.get("some_field");
// 使用 ValUtil 转换
Integer num = ValUtil.toInt(raw, 0);
List<String> list = ValUtil.toList(raw, String.class);
User user = ValUtil.toObj(raw, User.class);