JQuery DataTable 结合SpringMVC+Spring Data JPA应用(二)

在上一节中配置好了DataTable的配置,接下来介绍关于后台实现分页、条件查询、排序的方法。

DataTable后台分页、条件查询、排序
1.DataTable参数的接收

后台代码需要接收的参数有:

  • 当前记录数
  • 每页显示记录
  • 排序的列(可能有多个)
  • 排序列的方向 ASC/DESC(可能有多个)
  • 当前请求次数
  • 排序列的数量
  • 自定义查询的参数

然后再来看上一节中DataTable的基础配置中,有以下代码:

function retrieveData( sSource, aoData, fnCallback ) {     
        //查询条件称加入参数数组     
        var rentRuleId =document.getElementById('rentRuleId').value;  
        //alert(rentRuleId);
        $.ajax( {     
            type: "POST",
            url: sSource,   
            dataType:"json",  
            data: "jsonParam="+JSON.stringify(aoData)+"&isHistory=0&rentRuleId="+rentRuleId,  
            success: function(data) {   
               //$("#url_sortdata").val(data.aaData);  
                fnCallback(data); //服务器端返回的对象的returnObject部分是要求的格式     
            }     
        });    
    } 

这段代码是是关键,它定义了关于DataTable的自己的参数适用jsonParam来接收,而关于自定义的查询参数如isHistory、rentRuleId都适用相应的属性来接收。但是也有一些方法是将这些参数放在aoData里面,然后用同一个对象接收所有的数据。这里先不考虑。
这时,相应的Controller就应该写成这样:
dataTableTestController.java

@RequestMapping(value = "/list", method = {RequestMethod.POST })
    protected void list(String jsonParam,ChargeRuleModel model,HttpServletResponse response){
        xxxx;//这里避免干扰先不写
    }

第一,通过ChargeRuleModel来接收自定义查询的参数。
第二,用jsonParam来接受相应的jsonString。jsonParam的格式如下:

[{"name":"sEcho","value":1},            //请求次数
{"name":"iColumns","value":5},          //列数 
{"name":"sColumns","value":",,,,"},     //这个没查到
{"name":"iDisplayStart","value":0},     //记录起始,0表示第一条
{"name":"iDisplayLength","value":10},   //每页显示的记录数
{"name":"mDataProp_0","value":"key"},   //第一列名称 
{"name":"bSortable_0","value":false},   //第一列是否可以排序
{"name":"mDataProp_1","value":"rentRuleId"},//第二列名称
{"name":"bSortable_1","value":true},    //第二列是否可以排序  
{"name":"mDataProp_2","value":"ruleName"},
{"name":"bSortable_2","value":true},
{"name":"mDataProp_3","value":"isEnable"},
{"name":"bSortable_3","value":true},
{"name":"mDataProp_4","value":"id"},
{"name":"bSortable_4","value":true},
{"name":"iSortCol_0","value":1},//第一个排序,value值得是第几列 
{"name":"sSortDir_0","value":"asc"},//排序是正序还是倒叙
{"name":"iSortingCols","value":1}]  //一共有几列排序

看出来了么,其实是个JsonArray,所以常见的方法是这样:

JSONArray ja = (JSONArray) JSONArray.parse(aoData);
        //分别为关键的参数赋值
        for (int i = 0; i < ja.size(); i++) {
            JSONObject obj = (JSONObject) ja.get(i);
            if (obj.get("name").equals("sEcho"))
                sEcho = obj.get("value").toString();
            if (obj.get("name").equals("iDisplayStart"))
                iDisplayStart = obj.get("value").toString();
            if (obj.get("name").equals("iDisplayLength"))
                iDisplayLength = obj.get("value").toString();
            if (obj.get("name").equals("sSearch"))
                sSearch = obj.get("value").toString();
        }

对于一个JsonArray操作多麻烦,而且格式那么统一,“name”、“value”让人想起什么?

protected Map<String,Object> covertJsonStringToHashMap(String jsonParam){
        JSONArray jsonArray = JSONArray.parseArray(jsonParam);
        Map<String,Object> map = Maps.newHashMap();
        for(int i=0;i<jsonArray.size();i++){
            JSONObject jsonObj = jsonArray.getJSONObject(i);
            map.put(jsonObj.getString("name"), jsonObj.get("value"));
        }
        return map;
    }

这时候考虑到可能有实现多个列的排序,另外不要再service再去判断参数中第一列到底对应的是数据库那个字段,所以就需要对于Map再进一步操作。这时引入一个对象 DataTableParameter。

public class DataTableParameter {
    private int sEcho; //请求服务器端次数
    private int iDisplayStart;//其实记录,第一条为0
    private int iDisplayLength;
    private int iColumns;
    private List<String> mDataProps; //列的Name列表
    private List<Boolean> bSortables;//列对应是否能排序
    private int iSortingCols;
    private List<Integer> iSortCols;    //排序列的编号
    private List<String> iSortColsName; //排序列的名称
    private List<String> sSortDirs;     //排布列排序形式 Asc/Desc
    ......
    //seter and getter
}

然后引入一个方法

protected DataTableParameter getDataTableParameterByJsonParam(String jsonParam){
        Map<String,Object> map = covertJsonStringToHashMap(jsonParam);
        int sEcho = (int) map.get("sEcho"); 
        int iDisplayStart = (int) map.get("iDisplayStart");
        int iDisplayLength = (int) map.get("iDisplayLength");
        int iColumns = (int)map.get("iColumns");
        int iSortingCols = (int)map.get("iSortingCols");

        List<String> mDataProps = Lists.newArrayList();
        List<Boolean> bSortables = Lists.newArrayList();
        for(int i=0;i<iColumns;i++){
            String dataProp = (String) map.get("mDataProp_"+i);
            Boolean sortable = (Boolean) map.get("bSortable_"+i);
            mDataProps.add(dataProp);
            bSortables.add(sortable);
        }

        List<Integer> iSortCols = Lists.newArrayList();
        List<String> sSortDirs = Lists.newArrayList();
        List<String> iSortColsName = Lists.newArrayList();
        for(int i=0;i<iSortingCols;i++){
            Integer sortCol = (Integer) map.get("iSortCol_"+i);
            String sortColName = mDataProps.get(sortCol);
            String sortDir = (String) map.get("sSortDir_"+i);
            iSortCols.add(sortCol);
            sSortDirs.add(sortDir);
            iSortColsName.add(sortColName);
        }

        return new DataTableParameter(sEcho, iDisplayStart, iDisplayLength, iColumns, mDataProps, bSortables, iSortingCols, iSortCols, sSortDirs,iSortColsName);
    }

这时Controller就变成这样了:

@RequestMapping(value = "/list", method = {RequestMethod.POST })
    protected void list(String jsonParam,ChargeRuleModel model,HttpServletResponse response) {
        DataTableParameter dataTableParam = getDataTableParameterByJsonParam(jsonParam);
        //......
    }

参数接收处理完毕。

2.DataTable返回页面参数

DataTable.java

public class DataTable<T>{

    private List<T> aaData;//数据
    private int iTotalDisplayRecords;//得到的记录数
    private int iTotalRecords;//数据库中记录数
    private int sEcho; //请求服务器端次数
    //getter and setter
}

aaData接收相应的查询返回结果,sEcho在请求一次后就加1.

完整的Controller方法如下:

@RequestMapping(value = "/list", method = {RequestMethod.POST })
    protected void list(String jsonParam,ChargeRuleModel model,HttpServletResponse response) {
        DataTableParameter dataTableParam = getDataTableParameterByJsonParam(jsonParam);
        List<ChargeRuleModel> aaData = chargeRuleService.list(model, dataTableParam);
        DataTable<ChargeRuleModel> dt = new DataTable<ChargeRuleModel>();
        int sEcho = dataTableParam.getsEcho()+1;
        dt.setAaData(aaData);
        dt.setsEcho(sEcho);
        dt.setiTotalDisplayRecords(aaData.size());
        dt.setiTotalRecords(aaData.size());
        response.setCharacterEncoding("utf-8");
response.getWriter().write(JSONObject.toJSONString(dt));
    }
3.动态查询与分页

Service方法如下:

public List<ChargeRuleModel> list(ChargeRuleModel model, DataTableParameter dataTableParam) {
        Pageable pageRequest = buildPageRequest(dataTableParam,ChargeRule.class);
        Specification<ChargeRule> spec = buildSpecification(model);
        List<ChargeRule> chargeRules = chargeRuleDao.findAll(spec, pageRequest).getContent();
        List<ChargeRuleModel> chargeRuleModels = null;
        // PO到VO的转化
        Map<String, String> map = Maps.newHashMap();
        map.put("sourcePro1", "ruleAppliType.id");
        map.put("targetPro1", "ruleAppliTypePK");
        map.put("sourcePro2", "ruleAppliType.name");
        map.put("targetPro2", "ruleAppliTypeName");

        chargeRuleModels = BeanUtils.copyPropertiesBylist(chargeRules, ChargeRuleModel.class, map);
        return chargeRuleModels;
    }

    private Specification<ChargeRule> buildSpecification(ChargeRuleModel model) {
        String rentRuleId = model.getRentRuleId();
        boolean isHistory = model.getIsHistory();
        String historyRentRuleId = model.getHistoryRentRuleId();

        return new Specification<ChargeRule>() {
            @Override
            public Predicate toPredicate(Root<ChargeRule> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<Predicate>();

                list.add(cb.equal(root.get("isHistory"), isHistory));

                if (StringUtils.isNotNullAndEmpty(historyRentRuleId)) {
                    list.add(cb.equal(root.get("rentRuleId"), historyRentRuleId));
                }
                if (StringUtils.isNotNullAndEmpty(rentRuleId)) {
                    list.add(cb.like(root.get("rentRuleId"), "%" + rentRuleId + "%"));
                }

                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        };
    }

    protected PageRequest buildPageRequest(DataTableParameter dataTableParam,Class<T> entityClass){
        int iDisplayStart = dataTableParam.getiDisplayStart();
        int iDisplayLength = dataTableParam.getiDisplayLength();
        List<String> iSortColsName = dataTableParam.getiSortColsName();
        List<String> sSortDirs = dataTableParam.getsSortDirs();

        Sort sort = null;
        if(!ListUtils.isNullOrEmpty(iSortColsName)){
            validatorSortColumns(iSortColsName,entityClass);
            List<Order> orders = Lists.newArrayList();
            for(int i=0;i<iSortColsName.size();i++){
                String sortCol = iSortColsName.get(i);
                String dir = sSortDirs.get(i);
                orders.add(new Order(getDirectionByDirString(dir),sortCol));
            }
            sort = new Sort(orders);
        }
        return new PageRequest(iDisplayStart / iDisplayLength, iDisplayLength, sort);
    }

因为经过之前封装成DataTableParam之后,分页以及排序的方法都是相同的。所以实际上我是把buildPageRequest(..)方法放在BaseService中的。PageRequest、Specification是Spring data jpa的东西,所以不介绍了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值