Mybatis查询动态列,转Vo


Mybatis查询动态列,转Vo

原创 于 2025-11-10 11:01:50 发布 · 粉丝可见 · 91 阅读 · 0 · 0 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/154641731

目录

[TOC]

简要

今日工作的时候,老项目有个很蛋疼的逻辑,表格列是不定的  其元素列以及列数可以进行修改,导致如果需要进行查询相对应的数据的时候,需要通过 for 循环 查询的列 字段,导致 Vo 层的属性数量也是不定的。

解决思路:

1、临时Map 映射存储

由于Select查询 字段无论如何都有相对应的键对值,可以Mapper 层使用 Map 映射存储、

2、Map 转 Vo

这里的VO,实际上还是一个 Map ,只是不同的是,有一些字段是可以确定的,而不定的字段就是用 Map 进行存储。然后通过反射,将 动态列 写入 Vo 中的 Map

解决方法(示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 
/**
* @param column
* @return
* @author Angindem
* @description {
* 动态列中获取培训计划类型编号Typeno,
* 使用方法:
* 动态列字段命名格式应该为: xxx_#{typeno}
* 示例: 假设 typeno = 0101
* 动态列字段命名: xxx_0101 或 col_0101
* SQL语法中字段别名方式: `as` , 查询字段: select (sumDemoStr as col_0101) from table
* 动态列参考模板:【
* <foreach collection="columns" separator="," item="item" >
* sum( DECODE( a.TYPENO, #{item}, 1, 0 )) real_${item}
* </foreach>
* 】
* }
* @since 2025/11/7 - 16:26
*/
// 添加类型转换辅助方法
private static String getTarinYypeNoByColumn(String column) {
if (StringUtils.isEmpty(column)) return null;
// 查找最后一个下划线后的内容
int lastUnderscoreIndex = column.lastIndexOf("_");
if (lastUnderscoreIndex > 0 && lastUnderscoreIndex < column.length() - 1) {
String suffix = column.substring(lastUnderscoreIndex + 1);
// 检查后缀是否为数字
if (suffix.matches("\\d+")) {
return suffix;
}
}
return null;
}

/**
* @param item
* @param trainTypesList
* @param clazz
* @param <T>
* @return
* @author Angindem
* @description 动态列 Map 转 VO ,前提条件: Vo 中要有动态列属性 Columns
* @since 2025/11/8 - 17:19
*/
public static <T> T mapToPageItemVo(Map item, List<TrainTypesVo> trainTypesList, Class<T> clazz) {
try {
// 通过反射创建实例
T itemVo = clazz.getDeclaredConstructor().newInstance();

// 拷贝基础属性
BeanUtil.copyProperties(item, itemVo);

// 处理动态列数据
List<Map<String, Object>> dynamicColumns = new ArrayList<>();
Map<String, Map<String, Object>> has = new HashMap<>();

for (Object key : item.keySet()) {
String typeNo = getTarinYypeNoByColumn(key.toString());
if (StringUtils.isNotEmpty(typeNo)) {
if (!has.containsKey(typeNo)) {
Map<String, Object> maps = new HashMap<>();
has.put(typeNo, maps);
}
if (!has.get(typeNo).containsKey("typeno")) {
has.get(typeNo).put("typeno", typeNo);
has.get(typeNo).put("typename", trainTypesList.stream()
.filter(items -> items.getTypeno().equals(typeNo))
.findFirst()
.get()
.getTypename());
}
has.get(typeNo).put(key.toString().substring(0, key.toString().indexOf("_")), item.get(key));
}
}
// 添加动态列到列表
for (Map<String, Object> value : has.values()) {
dynamicColumns.add(value);
}
// 通过反射调用 setColumns 方法
clazz.getMethod("setColumns", List.class).invoke(itemVo, dynamicColumns);
return itemVo;
} catch (Exception e) {
throw new RuntimeException("创建实例或设置列数据失败", e);
}
}

觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭

微信二维码

wechat pay

支付宝二维码

ali pay

Mybatis查询动态列,转Vo
http://blog.angindem.cn/2025/11/10/Angindem-CSDN博客/196_196/
作者
Angindem
发布于
2025年11月10日
许可协议