业务上需要存储动态列的数据 通过行列互转的方式实现
数据库中动态列的几种设计思路
-
使用数据库DDL进行动态创建
-
使用数据库预留字段(宽表)
-
使用数据库中的json数据类型
-
使用非关系型数据库(MongoDB等)
这是网上给出的几个基本思路,考虑到我们业务上的功能不太适合这些方法,所有最后选择通过行列互转的方式实现。
数据库设计
数据库使用了4个字段,key是原表中的列名,value是对应的值,sort有两个作用,排序和分组,row_id用于关联主表。数据库结构如下表table
。
名称 | 类型 | 注释 |
---|---|---|
COL_KEY | VARCHAR2(50) | 列名(key) |
COL_VALUE | VARCHAR2(255) | 列值(value) |
ROW_ID | VARCHAR2(50) | 所属主表id |
SORT | NUMBER | 排序 |
行转列(存储)
第一步是将动态列的结果集存储起来
列名1 | 列名2 | 列名3 | ... | 列名N |
---|---|---|---|---|
a | b | c | ... | e |
1 | 2 | 3 | ... | 5 |
A | B | C | ... | E |
6 | 7 | 8 | ... | 10 |
结果集返回的数据是List<Map>
结构,这里不做太多赘述了
直接上代码
//存入列表(列转行)
List<Table> list= new ArrayList<>();//新建一个table类型的集合
long index = 1;//排序索引
for (Map map : list) { //list是返回的结果集,直接遍历
// 通过keySet方法获取list中一个map的所有key
Set<String> keySet = map.keySet();
for (String s : keySet) { //继续遍历所有key
//新建临时对象
Table table = new Table();
table.setColKey(s);//设置属性Key
//设置属性value,通过get(key)的方式,同时将value的类型都处理成String
table.setColValue(String.valueOf( map.get(s)));
table.setSort(index);//设置分组条件的同时还能排序
table.setRowId(“自定义”);//根据传过来的值设置属于那个主表
list.add(table);//加入集合中
}
index++;
}
列转行(显示)
假设上一步已经将数据存入table表中
col_key | col_value | row_id | sort |
---|---|---|---|
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
列名1 | a | id | 1 |
1 | 2 | 3 | ... |
A | B | C | ... |
6 | 7 | 8 | ... |
存完之后下一步就该显示了,虽然我们是通过列的方式存的,但是我们显示的时候还是应该将列转换成行来显示,就和存之前的结果集一样
我用的数据库是Oracle,因此有两种方式来实现
SQL通用方式
select sort,
MAX(case col_key when '状态' then col_value end) as AAA,
MAX(case col_key when '创建者' then col_value end) as AAA,
MAX(case col_key when '编号' then col_value end) as AAA,
MAX(case col_key when '类型' then col_value end) as AAA
from monitor_detail
where monitor_id = 235
group by sort order by sort
标签:java,--,列名,value,col,key,互转,table,id
From: https://www.cnblogs.com/Cloong/p/17268281.html