1.添加和修改功能
①准备编辑对话框
- 实现添加或修改功能之前,需要准备一个编辑对话框
- 在在对话框中准备一个填写信息的表单,和保存取消按钮
- 将id项设为隐藏域
- 为密码项的tr标签设置shower属性(名字随便取)
部门项需要特别注意
因为添加或修改功能,后台都是Employee对象接受数据并封装。所以必须传department.id属性,后台才能成功接受并封装Employee对象
<tr>
<td>部门:</td>
<%--添加时或者修改时,后台是Employee对象接受,所以传department.id属性Employee才有--%>
<td><input name="department.id" class="easyui-combobox"
data-options="valueField:'id',textField:'name',url:'/department/list',panelHeight:'auto'" /></td>
</tr>
完整代码
<%--添加或保存对话框--%>
<div id="dialog" class="easyui-dialog" title="用户管理"
data-options="iconCls:'icon-save',resizable:true,modal:true,closed:true,buttons:'#buttons'">
<%--信息表单--%>
<form id="editForm" method="post">
<table cellpadding="5">
<input id="employeeId" type="hidden" name="id"/>
<tr>
<td>用户名:</td>
<td><input class="easyui-textbox" type="text" name="username" data-options="required:true"></input></td>
</tr>
<tr shower="true">
<td>密码:</td>
<td><input class="easyui-passwordbox" type="password" name="password" data-options="required:true"></input></td>
</tr>
<tr>
<td>邮箱:</td>
<td><input class="easyui-textbox" type="text" name="email" data-options="required:true,validType:'email'"></input></td>
</tr>
<tr>
<td>年龄:</td>
<td><input class="easyui-textbox" name="age" data-options="required:true"></input></td>
</tr>
<tr>
<td>年龄:</td>
<%--添加时或者修改时,后台是Employee对象接受,所以传department.id属性Employee才有--%>
<td><input name="department.id" class="easyui-combobox"
data-options="valueField:'id',textField:'name',url:'/department/list',panelHeight:'auto'" /></td>
</tr>
</table>
</form>
</div>
<%--保存/取消按钮--%>
<div id="buttons">
<a href="#" data-method="save" class="easyui-linkbutton c3">保存</a>
<a href="#" data-method="close" class="easyui-linkbutton c4">关闭</a>
</div>
②添加功能
添加功能实现步骤
- 每次添加时,先清理对话框中的表单数据
- 显示密码项
- 在页面中央打开对话框
add(){
//每次打开对话框先清理表单数据
editForm.form("clear");
$("*[shower]>td>input").textbox("enable");
//显示密码项
$("*[shower]").show();
//点击添加,弹出对话框
dialog.window("open").window("center");
}
③修改功能
- 修改时,需要判断是否选中一行
- 每次修改时,先清理对话框中的表单数据
- 修改时,不需要修改密码,设置标识,隐藏密码项
- 禁用密码,不让让传值
- 设置部门回显后再,回显表单
部门回显需要特别注意
- 为row添加一个【department.id】属性,并将部门id赋值给它
- 这时row中【department.id】属性和input标签中 name="department.id"对应成功,完成部门回显
if(row.department){//如果部门存在
row["department.id"] = row.department.id;
}
完整代码
update(){
//修改时,需要判断是否选中一行
//获取行
var row = datagrid.datagrid("getSelected");
if(!row){
//提示选中
$.messager.alert('提示','请选中一行再删除','warning');
return;
}
//每次打开对话框先清理表单数据
editForm.form("clear");
//修改时,不需要修改密码,设置标识,隐藏密码项
$("*[shower]").hide();
//禁用密码,不让让传值
$("*[shower]>td>input").textbox("disable");
//部门回显
if(row.department){//如果部门存在
/*
* 为row添加一个【department.id】属性,并将部门id赋值给它
* 这时row中【department.id】属性和input标签中 name="department.id"对应成功,完成部门回显
* */
row["department.id"] = row.department.id;
}
//回显
editForm.form("load",row);
//点击添加,弹出对话框
dialog.window("open").window("center");
}
④保存(添加和修改)
根据有无id判断是添加还是修改,选择对应路径
save(){
//默认添加路径
var url = "/employee/save";
//获取id
var employeeId = $("#employeeId").val();
if(employeeId){
url = "/employee/update?_cmd=update";
}
editForm.form('submit', {
url:url,
onSubmit: function(){
//提交前执行的操作 一般用于验证
return $(this).form("validate");
},
success:function(data){
//从后台获取到json格式的字符串{"success":true,"msg":null}
//将json格式字符串转换为json对象
var result = JSON.parse(data);
//如果添加成功
if(result.success){
//重新加载数据
datagrid.datagrid("reload");
}else{
//添加失败返回失败信息
$.messager.alert('提示',`添加失败了,原因是:${result.msg}`,'error');
//$.messager.alert('提示','添加失败了,原因是:'+result.msg,'error');
}
//关闭对话框
itsource.close();
}
});
}
⑤添加和修改后台代码
修改时-数据丢失问题
问题原因:
因为前台禁止了传递密码到后台,后台默认封装对象Employee是由Spring通过new方式创建,默认密码值为null,将原有密码覆盖了。
解决方式:(先查找,再封装)
- 创建一个方法接受前台id,通过id查找到对应Employee对象
- 为该方法添加@ModelAttribute注解(每次请求都会先于其他方法执行)
- 将查找到的Employee对象交给修改方法(这时该方法不是Spring创建的,查询出来的对象有密码就是原有密码)
代码如下:
/*
* @ModelAttribute每次请求都会吗先执行该方法
* 两个editEmployee必须相同
* 先查找,再封装
* */
@ModelAttribute("editEmployee")
public Employee aaa(Long id,String _cmd){
if(id != null && "update".equals(_cmd)){//只有修改数据,才返回查找的对象
Employee employee = employeeService.findOne(id);
return employee;
}
return null;
}
//添加功能
@RequestMapping("/save")
@ResponseBody
public JpaResult save(Employee employee){
return saveOrUpdate(employee);
}
//修改功能
@RequestMapping("/update")
@ResponseBody
public JpaResult update(@ModelAttribute("editEmployee")Employee employee){
return saveOrUpdate(employee);
}
//添加或者删除
public JpaResult saveOrUpdate(Employee employee){
try {
employeeService.save(employee);
System.out.println("hahaha");
//添加成功
return new JpaResult();
} catch (Exception e) {
e.printStackTrace();
//添加失败
return new JpaResult(false,e.getMessage());
}
}
3.完成部门模块CRUD
和Employee实现CRUD一样
- 创建Department实体类
- 拷贝employee相关文件,
- 将Employee替换为Department
- 将employee替换为department
- 查询对象只保留作为查询条件的字段
- 部门首页查询显示部门的对应字段信息
2.员工与部门关连
多个员工对应一个部门(多对一)
@Entity
@Table(name = "employee")
public class Employee extends BaseDomain{
private String username;
private String password;
private String email;
private Integer age;
private String headImage;
//多个员工对应一个部门
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
//getter,setter,toString...
}
①部门和头像显示问题
我们发现员工首页,头像和部门信息不能正确显示
问题原因:
数据库中头像存储的是头像的地址值,所以需要进行格式修改
部门存储的是一个department对象,需要显示对象的name属性(部门名称)
解决方法:
在前台数据表格,头像项的data-options属性添加formatter:imgFormat
部门项的data-options属性添加formatter:deptFormat
格式处理函数代码
//图片格式
function imgFormat(v) {
return `<image src="${v}" style="width: 50px;height: 50px;" />`;
}
//部门对象格式
function deptFormat(v) {
return v?v.name:"没部门";
}
<%--数据表格(展示当前模块数据)--%>
<table id="datagrid" class="easyui-datagrid" style="width:400px;height:250px"
data-options="url:'/employee/page',fitColumns:true,singleSelect:true,fit:true,pagination:true,toolbar:'#tb'">
<thead>
<tr>
<th data-options="field:'id',width:100">编码</th>
<th data-options="field:'username',width:100">名称</th>
<th data-options="field:'headImage',width:100,formatter:imgFormat">头像</th>
<th data-options="field:'password',width:100,align:'right'">密码</th>
<th data-options="field:'email',width:100,align:'right'">邮箱</th>
<th data-options="field:'age',width:100,align:'right'">年龄</th>
<th data-options="field:'department',width:100,align:'right',formatter:deptFormat">部门</th>
</tr>
</thead>
</table>
②部门查询注意事项
departmentId:表示前台传过来的id
“department.id”:表示Employee对象的属性
.eq( departmentId!=null, "department.id", departmentId)
EmployeeQuery查询对象代码
public class EmployeeQuery extends BaseQuery{
private String username;
private String email;
private Integer age;
//前台传过过来的部门id值
private Long departmentId;
/*
* .gt( departmentId!= null, "department.id", departmentId)
* department.id是Employee中的属性
* departmentId是前台传过过来的部门id值
* */
@Override
public Specification createSpec(){
Specification<Employee> spec = Specifications.<Employee>and()
.like(StringUtils.isNoneBlank(username), "username", "%" + username + "%")
.like(StringUtils.isNoneBlank(email), "email", "%" + email + "%")
.eq( departmentId!=null, "department.id", departmentId)
.build();
return spec;
}
getter,setter
}
departmentId与后台查询对象字段名必须一致
<%--查询表单--%>
<form id="searchForm" method="post">
用户名: <input name="username" class="easyui-textbox" style="width:80px">
邮箱: <input name="email" class="easyui-textbox" style="width:80px">
<%--
departmentId与后台查询对象字段名一致
valueField:部门id可以
textField:对应id显示的内容
--%>
部门:<input name="departmentId" class="easyui-combobox"
data-options="valueField:'id',textField:'name',url:'/department/list',panelHeight:'auto'" />
<a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询</a>
</form>