云悦智销项目03_CRUD_数据丢失

一.完成了高级分页查询
1.1 分页查询
1.1.1 准备分页条 pagination:true

<table class="easyui-datagrid" id="employeeDataGrid"
       data-options="... pagination:true">
     ...

1.1.2 后台返回分页数据

需要返回的结构:{total:23,rows:[...]}
准备相应的UIPage类
public class UIPage<T> {

    private Long total; //总条数
    private List<T> rows; //每页数据

    public UIPage(Page page) {
        total = page.getTotalElements();
        rows = page.getContent();
    }

    public Long getTotal() {
        return total;
    }

    public void setTotal(Long total) {
        this.total = total;
    }

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }
}

EmployeeController中添加返回UIPage的方法

/**
 * 准备分页方法
 * @param query
 * @return
 */
@RequestMapping("/page")
@ResponseBody
public UIPage page(EmployeeQuery query){
    //return employeeService.queryPage(query);
    return new UIPage(employeeService.queryPage(query));
}

1.1.3 后台接收分页数据
我们必需保证前台传的数据(当前页与每页条数)和咱们后台的Query中的名称相同 BaseQuery中做修改

//兼容easyui的分页 ctrl+f9
public void setPage(int currentPage) {
    this.currentPage = currentPage;
}
public void setRows(int pageSize) {
    this.pageSize = pageSize;
}

1.2 完善咱们的Employee功能
1.2.1 完成Department的CRUD
拷备Employee再写一份即可
代码略(靠自己)
1.2.2 Employee对象

@Entity
@Table(name = "employee")
public class Employee extends BaseDomain {
    ...
    //头像
    private String headImage;
    //部门
    /**
     * hibernate自动为懒加载对象加上了一些属性
     * 但是这几个属性在SpringMVC生成json数据的数据,就会报错(No serializer)
     * Ignore:忽视
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "department_id")
    //@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
    private Department department;

   ...
}

1.2.3 懒加载引发的血案
1.2.3.1 noSession

 EntityManager提前关系了
- web.xml中配置Spring的过滤器
  <!--解决no-session的问题-->
  <filter>
    <filter-name>openEntityManager</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>openEntityManager</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

1.2.3.2 noSerializer
hibernate添加了一些字段(变成Json时报错)
解决方案一: 字段上加注解 @JsonIgnoreProperties(value={“hibernateLazyInitializer”,“handler”,“fieldHandler”})
解决方案二:自己配置(拷备过来用即可)

CustomMapper
public class CustomMapper extends ObjectMapper {
    public CustomMapper() {
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}

applicationContext-mvc.xml

 <!-- Spring MVC 配置 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>application/json; charset=UTF-8</value>
                    <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                </list>
            </property>
            <!-- No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题 -->
            <property name="objectMapper">
                <bean class="cn.itsource.aisell.common.CustomMapper"></bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

1.2.4 头像与部门的显示

employee.js加上format的方法
/**
 *
 * @param v(value) :当前的数据
 * @param r(row) : 当前行的数据
 * @param i(index) :索引
 * @returns {string}
 */
function imageFormat(v,r,i) {
    return `<img src='${v}' style="width:60px;height:60px;">`;
}
//部门的格式化
function deptFormat(v) {
    return v?v.name:"";
}

employee中的index.js 使用format方法

<table class="easyui-datagrid" id="employeeDataGrid"
       data-options="url:'/employee/page',fitColumns:true,singleSelect:true,fit:true,toolbar:'#toolbar',pagination:true">
    <thead>
        ...
        <th data-options="field:'headImage',width:100,formatter:imageFormat">头像</th>
        ...
        <th data-options="field:'department',width:100,formatter:deptFormat">部门</th>
    </tr>
    </thead>
</table>

1.3 高级查询
1.3.1 准备高级查询的条件

<div id="toolbar">
    ...
    <form id="searchForm" method="post">
        用户名: <input name="username" class="easyui-textbox" style="width:80px">
        邮箱: <input name="email" class="easyui-textbox" style="width:80px">
        部门: <input class="easyui-combobox" name="departmentId"
                   data-options="valueField:'id',textField:'name',url:'/department/findAll',panelHeight:'auto'" />
        <a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询</a>
    </form>
</div>

1.3.2 准备search方法
注:我们引入了**jquery的扩展js(jquery.jdirk.js)**才有serializeObject方法

 itsource = {
        ...
        //高级查询
        search(){
            //JQuery没有提供拿到json格式的数据
            //直接拿到要查询的值  {username:xx,...}
            var params =searchForm.serializeObject();
            // //grid刷新
            employeeDataGrid.datagrid('load',params);
        }
    };

二.删除功能
2.1 准备一个JsonResult类型
/**

  • 删除返回的信息
    */
public class JsonResult {
    //代表是否成功
    private boolean success = true;
    //代表相应的信息(一般是错误信息)
    private String msg;

    public JsonResult(){}
    public JsonResult(boolean success, String msg) {
        this.success = success;
        this.msg = msg;
    }
   ...
}

2.2 EmployeeController提供删除功能
/**

  • 前台会传一个id过来
  • 需要返回:{success:true/false,msg:“xx”}
  • 返回这种结构有两种方法:1种是**写map**, 1种是**直接返回对象**
    

*/

@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
    try {
        employeeService.delete(id);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        //失败后返回的结果
        return new JsonResult(false,e.getMessage());
    }
}

2.3 employee.js完成删除

 delete () {
    //1.拿到你选择的那一条数据 (easyui的datagrid中有这个功能)
    //  row就是你选择的这一行的数据
    var row = employeeDataGrid.datagrid("getSelected");
    //2.如果没有拿到数据,给一个提示,让他选中再执行(后面的代码就不运行) Messager alert
    if(row==null){
        //alert("没有货,滚蛋!"); //不建议使用 1.不同浏览器效果不一样 2.它会阻塞进程
        $.messager.alert('警告','没有货,滚蛋!',"info");
        return;
    }
    //3.如果拿到数据,给一个提示,是否要删除? Messager confirm
    $.messager.confirm('确认','您要狠心的干掉我嘛?',function(r){
        if (r){
            //4.如果要删除 -> 发送Ajax请求到后台进行数据删除 $.get/post("/employee/delete",{id:2},function(){....})
            //  后台会返回相应的数据 :{success:true/false,msg:xxx}
            //  如果成功,刷新datagrid
            $.get("/employee/delete",{id:row.id},function (result) {
                if(result.success){
                    //删除成功,刷新datagrid
                    employeeDataGrid.datagrid("reload");
                }else{
                    //删除失败,给出失败提示
                    $.messager.alert('失败','删除没有成功,原因是:'+result.msg,"error");
                }
            })
        }
    });
},

三.添加功能
3.1 准备添加的弹窗

<%--添加或者修改的弹出框--%>
<div id="editDialog" class="easyui-dialog" title="数据操作" style="padding: 25px; "
     data-options="iconCls:'icon-save',resizable:true,modal:true,buttons:'#btns',closed:true">
    <form id="editForm" method="post">
        <table>
            <tr>
                <td>名称</td>
                <td><input class="easyui-validatebox" type="text" name="username" data-options="required:true" /></td>
            </tr>
            <tr>
                <td>密码</td>
                <td><input class="easyui-validatebox" type="text" name="password" data-options="required:true" /></td>
            </tr>
            <tr>
                <td> 邮箱</td>
                <td><input class="easyui-validatebox" type="text" name="email" data-options="required:true" /></td>
            </tr>
            <tr>
                <td> 年龄</td>
                <td><input class="easyui-validatebox" type="text" name="age" data-options="required:true" /></td>
            </tr>
            <tr>
                <td> 部门</td>
                <td>
                    <input class="easyui-combobox" name="department.id"
                           data-options="valueField:'id',textField:'name',url:'/department/findAll',panelHeight:'auto',required:true" />
                </td>
            </tr>
        </table>
    </form>
    <div id="btns">
        <a href="javascript:;" data-method="save" class="easyui-linkbutton c2" data-options="iconCls:'icon-ok'">确定</a>
        <a href="javascript:;" data-method="close" class="easyui-linkbutton c5" data-options="iconCls:'icon-cancel'">取消</a>
    </div>
</div>

3.2 点击添加弹出容器

//添加(只是弹出form)
add(){
    //打开面板前把里面的数据清除
    editForm.form("clear");
    //把添加框(editDialog)打开
    editDialog.dialog("center").dialog("open");
}

3.3 后台准备添加功能
/**
 * 前台会传相应的数据(Employee)过来
 *  需要返回:JsonResult{success:true/false,msg:"xx"}
 */
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}

3.4 前台提交form表单

save(){
    /**
     * 1.把表单数据传到后台
     * 2.如果后台保存成功,返回{success:true},刷新页面
     *      失败:返回{success:false,msg:xxx}
     * 3.关闭弹出框
     */
    /**
     * 1.把表单数据传到后台
     */
    editForm.form('submit', {
        url:"/employee/save", //提交的路径
        //提交前做点什么 如果返回false,它就不提交数据
        onSubmit: function(){
            // do some check
            // return false to prevent submit;
            return $(this).form('validate');
        },
        //data是一个json字符串
        success:function(data){
            // {"success":true}
            //把一个Json字符串转成JSON对象
            //eval("("+data+")")
            var result = JSON.parse(data);
            if(result.success){
                //成功就刷新页面
                employeeDataGrid.datagrid("reload");
            }else{
                $.messager.alert('警告',`添加失败,原因是:${result.msg}`,"info");
            }
            //关闭面板
            itsource.close();
        }
    });
},

修改功能
1.1 在form中加上id

...

1.2 点击修改回显

itsource ={
    ...
     update () {
            //1.拿到选中的那一条数据
            var row = employeeDataGrid.datagrid("getSelected");
            //2.如果没有选中,给出提示
            if(row==null){
                $.messager.alert('警告','没有货,滚蛋!',"info");
                return;
            }
            //3.清空表单并弹出数据
            editForm.form("clear");
            editDialog.dialog("center").dialog("open");
            //4.完成咱们的数据回显
            /**
             * 部门的回显
             */
            if(row.department){
                row["department.id"] = row.department.id;
            }
            editForm.form("load",row);
        }
}

1.3 save(保存)和update(修改)分开
1.3.1 前端请求改变
//保存修改功能(调用后台保存)

save(){
    //添加功能的路径
    var url ="/employee/save";
    //拿到表单中的员工id,如果id存在,代表修改
    var employeeId = $("#employeeId").val();
    if(employeeId){
        url = "/employee/update?cmd=update";
    }
    /**
     * 1.把表单数据传到后台
     */
    editForm.form('submit', {
        url:url, //提交的路径
       ...
    });
},

1.3.2 后台方法添加

/**
 * 前台会传相应的数据(Employee)过来
 *  需要返回:JsonResult{success:true/false,msg:"xx"}
 */
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Employee employee){
     return this.saveOrUpdate(employee);
}

//修改方法
@RequestMapping("/update")
@ResponseBody
public JsonResult update(Employee employee){
    return this.saveOrUpdate(employee);
}

//添加或者修改
public JsonResult saveOrUpdate(Employee employee){
    try {
        employeeService.save(employee);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        return new JsonResult(false,e.getMessage());
    }
}

**

.数据丢失

**
2.1 数据丢失的原因
前台没有传过来
后台对象对没有传过来的值就设置为空
修改的时候执行sql就把空值设置进去、

2.2 数据丢失的解决方案
前台传过来(隐藏域)
sql不修改相应的字段
自己写sql直接控制
jpa在字段上加 @Column(updatable = false)
通过id获取对象,再把传过来的参传过来、
这些解决方案:动态更新

2.3 解决数据丢失的代码
咱们解决了数据丢失后修改员工的部门时会出现一个n-to-n的错误,在获取员工对象后把它的部门设置为Null即可解决
2.3.1 更新前的操作

/**
 * @ModelAttribute:只要你通过前台调用我的方法,我就要执行这个方法中的内容
 *
 */
@ModelAttribute("editEmployee")
public Employee beforeUpdate(Long id,String cmd){
    //我想要的是,只有修改执行相应功能
    if(id!=null && "update".equals(cmd)) {
       //根据id拿到相应的对象
        Employee employee = employeeService.findOne(id);
        //把关连对应的值设置为空,就可以解决n-to-n的问题
        employee.setDepartment(null);
        return employee;
    }
    return null;
}

2.3.2 修改方法获取Employee对象
//修改方法
/**
*我们的这个employee对象中从 beforeUpdate中获取的
*/

@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editEmployee") Employee employee){
    return this.saveOrUpdate(employee);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值