需求描述:不同系统拥有不同的用户表,如果新增一个系统的话,则需要新增用户表,此时如果在页面展示的话,则会出现问题,显得写的很死,不能灵活调用。
现想针对新增系统用户表的时候能做动态处理,不管新增任何表,都可以动态进行查询,新增,修改,删除操作,不需要后端新增接口,进行增删改查操作。
所需条件:
查询:需用户表名,(包含模糊查询)查询参数
表结构:
代码:查询,展示详情
controller:
@ApiOperation("查询啊")
@RequestMapping(value = "/personManagementDetail", method = RequestMethod.POST)
public MapOutput personManagementDetail(String userTbname, String accountNumber, Integer pageNum, Integer pageSize) {
//查询系统表中是否存在新增的用户表
List<EditAndUserOutputDto> editAndUserEntity = pactera_SystemService.getUserTbNameAndEdit(userTbname);
Map maps = new HashMap();
List<String> stringList = new ArrayList<>();
//查询需要展示的用户表的表名,字段名,字段描述,用来动态展示title和body
List<TitleOutput> titleOutputList = pactera_SystemService.getFieldInformation(userTbname);
List list = new ArrayList();
for (int i = 0; i < titleOutputList.size(); i++) {
Map map = new HashMap<>();
map.put("key", titleOutputList.get(i).getFieldName());
map.put("name", titleOutputList.get(i).getFieldDescription());
list.add(map);
String fieldName = titleOutputList.get(i).getFieldName();
stringList.add(fieldName);
}
if (editAndUserEntity.size() == 0) {
maps.put("header", list);
maps.put("body", 0);
} else {
//当系统表中拥有此用户表时,进行查询,用来展示数据
PageInfo<Map<String, Object>> lists = userService.getBodyResult(userTbname, accountNumber, pageNum, pageSize, stringList);
List<Map<String, Object>> body = lists.getList();
maps.put("header", list);
maps.put("body", body);
}
//0是可编辑状态,1是不可编辑状态
if ("User".equals(userTbname)) {
maps.put("edit", 1);
} else {
maps.put("edit", 0);
}
return new MapOutput(200, "成功", null, maps);
}
对应mapper.xml
用来查询表结构sql
SELECT
表名 =
CASE
WHEN a.colorder= 1 THEN
d.name ELSE ''
END,字段序号 = a.colorder,字段名 = a.name,
字段说明 = ISNULL( g.[value], '' )
FROM
syscolumns a
LEFT JOIN systypes b ON a.xusertype= b.xusertype
INNER JOIN sysobjects d ON a.id= d.id
AND d.xtype= 'U'
AND d.name<> 'dtproperties'
LEFT JOIN syscomments e ON a.cdefault= e.id
LEFT JOIN sys.extended_properties g ON a.id= g.major_id
AND a.colid= g.minor_id
LEFT JOIN sys.extended_properties f ON d.id= f.major_id
AND f.minor_id= 0
WHERE
d.name LIKE '%User' --如果查询所有表,加上此条件
--d.name = 某用户表 如果只查询指定表,加上此条件
ORDER BY
a.id,
a.colorder;
用来查询数据(包含模糊查询的接口)
<select id="getBodyResult" resultType="java.util.Map">
select * from [${userTbname}]
where 1=1
<if test="accountNumber!=null and accountNumber!=''">
<trim prefix="and" suffixOverrides="or">
<foreach collection="list" open="" close="" separator=" " item="item">
${item} like CONCAT(CONCAT('%',#{accountNumber}),'%') or
</foreach>
</trim> </if></select>
查询结果:
效果展示:
新增接口:
需要前端传给我们所有字段和新增数据,以及用户表名,这边我的接受方式为
@Data
public class LikeUserInputDto {
private Object model;
private String tableName;
}
新增接口controller:
@ApiOperation("新增啊")
@RequestMapping(value = "/personManagementAdd", method = RequestMethod.POST)
public ResultOutput personManagementAdd(@RequestBody LikeUserInputDto inputDto) {
Object model = inputDto.getModel();
String tableName = inputDto.getTableName();
//将object对象转为map,字段顺序变化的
Map<String,Object> map = JSONObject.parseObject(JSONObject.toJSONString(model), Map.class);
userService.insertPerson(map,tableName);
return ResultOutput.success();
}
mapper.xml
<insert id="insertPerson" parameterType="java.util.Map">
insert into [${tableName}]
<foreach collection="model.keys" item="key" open="(" separator="," close=")">
${key}
</foreach>
VALUES
<foreach collection="model.values" item="val" open="(" separator="," close=")">
#{val}
</foreach>
</insert>
修改接口:
我这边建议前端能把所有的字段以及对应字段的参数都传过来,同时,还是需要一个用户表名。
但是此处修改的情况下,是需要根据id来选择修改哪条数据的,这时,如果我们用新增里的Object方法操作的话,id可能会出现在其他的位置,所用,用了下面的方法,保证字段顺序不变。
@ApiOperation("修改啊")
@RequestMapping(value = "/personManagementUpdate", method = RequestMethod.POST)
public ResultOutput personManagementUpdate(@RequestBody LikeUserInputDto inputDto) {
Object model = inputDto.getModel();
String tableName = inputDto.getTableName();
//将object对象转为map,保证字段顺序不变,同时遍历取出第一条数据(则是我们需要的id的字段名 和字段值),当然此方法只适用于我们的主键id在第一位的情况下
Map<String,Object> map = (Map) JSON.parse(JSONObject.toJSONString(model), Feature.OrderedField);
String value = null;
String key = null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
value = entry.getValue().toString();
key = entry.getKey();
if (value != null) {
break;
}
}
userService.updatePerson(map,tableName,key,value);
return ResultOutput.success();
}
mapper.xml
<update id="updatePerson" parameterType="java.util.Map">
update [${tableName}]
set
<foreach collection="model.keys" item="key" open="" close="" separator=",">
${key} = #{model[${key}]}
</foreach>
where
${id} = #{idValue}
</update>
删除:
@ApiOperation("删除啊")
@RequestMapping(value = "/personManagementDelete", method = RequestMethod.POST)
public ResultOutput personManagementDelete(@RequestBody LikeUserInputDto inputDto) {
Object model = inputDto.getModel();
String tableName = inputDto.getTableName();
Map<String,Object> map = (Map) JSON.parse(JSONObject.toJSONString(model), Feature.OrderedField);
String value = null;
String key = null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
value = entry.getValue().toString();
key = entry.getKey();
if (value != null) {
break;
}
}
userService.deletePerson(tableName,key,value);
return ResultOutput.success();
}
mapper.xml
<delete id="deletePersom">
delete from [${tableName}] where ${key} = #{value}
</delete>
至此,增删改查就写的差不多了,再多说一句,这种写法的话就是数据库所有字段全都暴露出去了,不是特别安全。(技术小白,不喜勿喷)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。