实现el-checkbox和el-select共用一张表的前后端数据传递
最近做了一个小的需求,因为是个前端小白,很多都要自己去查询解决办法,所以还是碰到许多困难的。
前端界面是一个多选框,还有多个选择器,不过他们是共用一张表的,id和name也是写死的,处理起来对于我还是比较的麻烦。
需求
1.先看前端要完成的功能吧,6个选择器加上一个多选框。
2.数据库中所对应的表
其中run_able字段存储的是多选框选择的内容,如果选择则在字段内有相应的数据,没有选择则值为空存储。code_type字段存储的是选择框选中的内容。我只需要操作前六项数据。
实现
前端页面展示的实现
1.这里用的是官网给的例子改的
2.因为多选框的内容是定好的,所以直接在data里面写好就行,el-checkbox-group绑定的是我们runable数组里面的值,应为lable绑定的时id,所以runable会和下面的id值对应,接下来的问题就是如何将runable从数据库中查出,在前端修改时保存进数据库并回显的问题了。
3.选择器的实现
绑定的值也是数组类型的
处理后端传过来的数据进行展示
1.这里定义了一个get方法接受后端的数据
2.后端我想的是传递多个对象,id和runable,所以前端只需要拿到id变成数组赋值给data就行了,当然后端也是可以直接传一个数组过来的。
3.这里的选择器的值我直接传递了一个数组过来
后端接口
实体类
@Data
public class CodeObj extends BaseEntity {
private Long id;
private String name;
private String description;
private String codeType;
private String runAble;
}
mapper
@Mapper
@Repository
public interface CodeObjMapper {
List<CodeObj> getCodeObj();
List<CodeObj>getRunable();
int updateRunable(List<CodeObj> codeObj);
int updateCodeType(List<CodeObj> codeObj);
}
service层
这里的codetype直接用流把他变成list集合传给前端了,runable我是直接传递了对象过去
public List<String> getCodeType() {
List<CodeObj> codeObj = this.codeObjMapper.getCodeObj();
List<String> collect = (List)codeObj.stream().map(CodeObj::getCodeType).collect(Collectors.toList());
return collect;
}
cotroller层
@GetMapping("/getRunable")
public AjaxResult getRunable(){
return AjaxResult.success(codeObjService.getRunable());
}
@GetMapping({"/getCodeType"})
public AjaxResult getCodeType() {
return AjaxResult.success(this.codeObjService.getCodeType());
}
实现前端页面内容的保存(修改)
多选框
1.这里的保存其实就是修改,因为数据库中已经把字段写死了。
2.前端我必须要传递这种数据返回给后端,因为前端对于多选框是只用了一个数组进行展示的,所以要想办法将id赋值进去,并且把runable变成一个对象。
因为我是个前端小白,所以只用到了比较笨的方法。
let tempArr = [];
let tempArrB=[];
this.codeForm.projectData.forEach(i=>{
tempArr.push({id: i.id,runAble: ''})
})
this.codeForm.projectData.forEach(i=>{
this.codeForm.getCodeObj.runable.forEach(item=>{
if(item===i.id){
tempArrB.push({id: i.id,runAble: i.name})
}
})
});
tempArr.forEach(item=>{
tempArrB.forEach(i=>{
if(item.id===i.id){
item = Object.assign(item,i)
}
})
})
3.定义两个空数组,tempArr定义基础的对象信息,tempArrB定义我们在前端页面所选中的信息,利用runable和projectDate中id相同得到runable的值放入temArrB。最后利用assign()方法进行去重。
选择器
对于选择器的话就是直接加一个id数组,然后将这个数据和codeType数组合并成对象数据就ok了
最后把codetype数组传给后端
updateCodeType(codeType).then(response=>{
})
后端(批量更新)
后端考虑的就主要是批量更新的问题了,因为是传过来多个对象的。
批量更新有几个思路,我用的是
case when
实现的
- 在service层对List集合进行for循环,每一条记录调用一次MySQL数据库。但是这样对于数据量大的情况下会大大消耗连接数据库的性能。
- 在MyBatis的xml文件中使用循环,每条语句用" ;"号隔开,使用事务监控语句执行的情况。但这样会直接报错,因为MyBatis默认不支持批量update语句的,要在连接JDBC的连接信息中加入一下字段:&allowMultiQueries=true。
- 使用case函数,将数据同时执行可以解决1的问题
case when的语法:
update cfg_obj set
run_able = case id
when 1 then "Mysql"
when 2 then "Oracle"
when 3 then "Cache"
end
where id in (1,2,3)
mapper
public interface CodeObjMapper {
List<CodeObj> getCodeObj();
List<CodeObj>getRunable();
int updateRunable(List<CodeObj> codeObj);
int updateCodeType(List<CodeObj> codeObj);
}
controller层
用RequestBody接收
@PutMapping("/updateRunable")
public AjaxResult updateRunable(@RequestBody List<CodeObj> codeObj ){
System.out.println(codeObj);
return AjaxResult.success(codeObjService.updateRunable(codeObj));
}
@PutMapping("/updateCodeType")
public AjaxResult updateCodeType(@RequestBody List<CodeObj> codeObj ){
System.out.println(codeObj);
return AjaxResult.success(codeObjService.updateCodeType(codeObj));
}
mapper.xml
这里主要用到了 foreach
实现循环插入,这里就是实现了上面的case when语句。
<update id="updateRunable" >
update cfg_monitor_obj set
<foreach collection="list" item="item" open="run_able=case id" close="end" >
when #{item.id} then #{item.runAble}
</foreach>
where id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.id}
</foreach>
</update>
<update id="updateCodeType" >
update cfg_monitor_obj set
<foreach collection="list" item="item" open="code_type=case id" close="end" >
when #{item.id} then #{item.codeType}
</foreach>
where id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item.id}
</foreach>
</update>