一.完成了高级分页查询

1.1 分页查询

1.1.1 准备分页条 pagination:true

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

1.1.2 后台返回分页数据

  • 需要返回的结构:{total:23,rows:[...]}
  1. 准备相应的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;
    }
}
  1. 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"})
  • 解决方案二:自己配置(拷备过来用即可)
  1. 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);
    }
}
  1. 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 头像与部门的显示

  1. 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:"";
}
  1. 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();
        }
    });
},

四.思考

  • 如果没有选中,不能修改
  • 选中后,点击修改,需要数据回显(部门回显看一下以前的代码)
  • 修改需要传id