环境:
springboot+mybatis
需求:
前台导入任意数据,后台经过处理后,根据处理后的字段,新建数据库表,并入库处理后的数据。
1.Mapper.xml中创建通用sql脚本,如下:
<select id="executeSql" parameterType="String">
${sqlContent}
</select>
2.创建表格,因为表明和字段名,字段数量未知,需要用StringBuffer讲sql拼接
StringBuffer sbInsert=new StringBuffer();
tId= "re_"+ UUIDUtils.uuid();
sbInsert.append("CREATE TABLE ").append(tId) .append("(");
// 遍历map中的key,来构造数据库字段
for(int tabIndex=0;tabIndex<tableTitle.size();tabIndex++){
sbInsert.append(" ").append(tableTitle.get(tabIndex)).append(" varchar(255) DEFAULT NULL");
if(tabIndex!=tableTitle.size()-1){
sbInsert.append(",");
}
}
sbInsert.append(")").append(";");
//执行通用sql语句
mapper.executeSql(sbInsert.toString());
3.开始拼接并执行insert语句
其实就是拼接出如下sql语句:
insert into re_5f7ba278190d4b46b4b3505495050541-->动态生成的表名
(amount,province_id,oder_time,order_id,order_name,province_name) -->动态生成的列名
VALUES
('308','340000','2018/10/1','DHDB190601022','奇瑞控股-系统','安徽省'),
('307','340000','2018/12/1','DHDB190601022','奇瑞控股-系统','安徽省'),
('69','340000','2019/3/1','DHDB190601022','奇瑞控股-系统','安徽省'),
('484','340000','2019/6/1','DHDB190601022','奇瑞控股-系统','安徽省'),
('370','340000','2018/8/1','DHDB180601009','奇瑞控股-咨询','安徽省'),
('464','340000','2020/8/1','DHDB200801098','奇瑞系统项目三期','安徽省'),
('447','120000','2021/1/1','DHBB210101037','一汽丰田系统项目','天津市'),
('37','120000','2020/3/1','DHBB200301032','中汽中心电子影像项目','天津市')
拼接代码如下:
StringBuffer sbInsert=new StringBuffer();
sbInsert.append("insert into ").append(tId).append("(")
//将动态生成的列名字段之间使用","隔开
.append(String.join(",",tableTitle))
.append(") VALUES ");
//遍历数据,根据表头取出数据,拼接数据
for(int countIndex=0;countIndex<list.size();countIndex++){
sbInsert.append("(");
Map<String, Object> stringObjectMap = list.get(countIndex);
for(int titleNUm=0;titleNUm<tableTitle.size();titleNUm++){
if(titleNUm!=0){
sbInsert.append(",");
}
sbInsert.append("'").append(stringObjectMap.get(tableTitle.get(titleNUm))).append("'");
}
sbInsert.append(")");
if(countIndex!=list.size()-1){
sbInsert.append(",");
}
}
//将sql传入公共sql处理模块,执行insert语句
mapper.executeSql(sbInsert.toString());
如下操作后,数据库表和表数据都可以在程序中动态生成,如下图:
题外:
postgrepsql 主键冲突则updata其他字段,主键不冲突则执行insert
INSERT INTO res_tname_tid_relatioin_t(tab_name,tab_id)
VALUES('zhangsan','112222')
ON conflict(tab_id)
DO UPDATE SET tab_name = 'true_tname'