elementui el-table前端动态选择表名展示表数据
elementui展示查询数据库所有表数据
场景:
前端传表名,和where查询的条件给后端。后端拼接成sql进行查询。然后返回给前端进行展示。
eg:前端传参三个 ,tableName="t_test",columnName="userName",columnValue="张三"
需要拼接成 select 具体字段 from t_test where userName = '张三'
避免sql注入风险,可以使用jdbcTemplate去执行动态拼接的sql:
【SpringBoot初级篇】JdbcTemplate常用方法_jdbctemplate查询一条数据-CSDN博客
页面示例如下图,通过点击“查询表信息”按钮,调用后端查询表信息接口。传参为操作对象、修改字段、修改值。后端拼成sql进行查询后端,然后返回前端。
返回前端后,前端经过处理将:name_姓名、age_年龄、gender_性别 进行拆分,一个作为prop,一个作为显示的label。
前端是做了动态处理的,也就是不管是什么表都可以展示出来对应的字段。
最后通过点击“查询表信息”按钮-->后端处理,返回前端-->前端处理-->弹窗展示示例如下图:
后端代码:
返回给前端的数据示例:
[{"NAME_姓名":"张三","AGE_年龄":"18"},{"NAME_姓名":"李四","AGE_年龄":"19"}]
@GetMapping("/info")
public R info(@RequestParam("tableName") String tableName,
@RequestParam(value = "columnName",required = false) String columnName,
@RequestParam(value = "columnValue",required = false) String columnValue){
//1、先根据tableName查询出该表的字段和字段注释
/**
* TableInfo :字段(columnName ,columnComment)
* sql:
* select column_name,column_comment from information_schema.columns where table_name='表名' and table_schema='数据库名'
*/
List<TableInfo> list = service.getColumnInfo(tableName);
// 2、拼接查询的sql
String sqlColumn = getSqlColumn(list);
String sql = "select "+sqlColumn+" from "+tableName;
if(StringUtils.isNotBlank(columnName) && StringUtils.isNotBlank(columnValue) ){
sql= sql + " where " +columnName+"="+columnValue;
}
// 执行sql 查询
/**
* xml
* <select id="runSql" parameterType="java.lang.String" resultType="java.util.Map">
* ${sqlStr,jdbcType=VARCHAR}
* </select>
*
* dao
* List <Map> runSql(String sqlStr)
*
*/
List<Map> mapList = service.runSql(sql);
return R.ok(mapList) ;
}
private String getSqlColumn(List<TableInfo> list){
StringBuilder sqlColumn = new StringBuilder();
for(TableInfo tableInfo : list){
String desc = tableInfo.getColumnComment();
//避免有括号内的注释 去掉括号内容
if(desc.indexOf("(")!=-1){
desc = desc.substring(0,desc.indexOf("("));
}
//别名拼接 eg:NAME as NAME_姓名
sqlColumn.append(tableInfo.getColumnName()+" as "+tableInfo.getColumnName()+"_"+desc+",");
}
// 去掉最后一个逗号
return sqlColumn.toString().substring(0,sqlColumn.toString().length()-1);
}
前端代码:
下面是弹窗子组件的代码,通过首页选择了表名、条件(字段名和字段值),点查询进行弹窗,显示查询后的页面。el-table-column 动态循环展示表数据
注:关闭弹窗或初始化弹窗的时候应该清理掉 data中字段赋值,避免有缓存。
<el-table :data="dataList">
<div v-for="(item,index) in cols" :key="index">
<el-table-column :prop="item.prop" :label="item.label" header-align="center">
<!-- 日期字段格式化 使用过滤器方法中的 formatDate -->
<template slot-scope="scope">
<span v-if="item.label.indexOf('日期')!=-1">{{scope.row[item.prop] | formatDate}}</span>
<span v-else >{{scope.row[item.prop]}}</span >
</template>
</el-table-column>
</div>
</el-table>
//data 定义
dataList:[],
cols:[],
tableMap:{},
data:{}//查询的参数 对象 有:tableName columnName columnValue
//方法
async queryTableInfo(){
var param = this.data;
// 后端接口调用
const{ code ,message,data} = await getTableInfo()
if(code=='1000'){
for(let i=0;i<data.length;i++){
let obj = data[i];
var newObj = new Object();
//循环对象
for (let key in obj){
var descKey = key.substring(key.lastIndexOf('_')+1);//这个是中文:姓名
var newKey = key.substring(0,key.lastIndexOf('_'));//key的英文:NAME
this.tableMap[newKey] = descKey ;//{'NAME':'姓名','AGE':'年龄'}
var val = obj [key];
newObj[newKey] = val;//新的对象变为:{'NAME':'张三','AGE':'18'}
}
this.dataList.push(newObj);
}
// cols:[{"label":"姓名","prop":"NAME"},{"label":"年龄","prop":"AGE"}]
for (let key in this.tableMap){
var colObj = {label:this.tableMap[key],prop:key};
this.cols.push(colObj)
}
}
}