springmvc+mybatis+pagehelper+datatables简单案例

本文介绍了一种使用Datatables插件实现服务器端分页的方法,包括前端页面展示、后端分页逻辑处理及数据交互过程。

首先需要有个工具类封装datatables分页所需要的数据,如下:

public class DataTablePageUtil<T> {

    /*------------------DT自动请求的参数(Sent parameters) begin--------------------*/
    /*
     * 绘制计数器。这个是用来确保Ajax从服务器返回的是对应的(Ajax是异步的,因此返回的顺序是不确定的)。 要求在服务器接收到此参数后再返回
     */
    private int draw; // 第几次请求
    /*
     * 第一条数据的起始位置,比如0代表第一条数据
     */
    private int start = 0;
    /*
     * 告诉服务器每页显示的条数,这个数字会等于返回的 data集合的记录数,可能会大于因为服务器可能没有那么多数据。
     * 这个也可能是-1,代表需要返回全部数据(尽管这个和服务器处理的理念有点违背)
     */
    private int length = 10; // 数据长度

    /*
     * 全局的搜索条件,条件会应用到每一列( searchable需要设置为 true )
     */
    private String search;

    /*
     * 如果为 true代表全局搜索的值是作为正则表达式处理,为 false则不是。
     * 注意:通常在服务器模式下对于大数据不执行这样的正则表达式,但这都是自己决定的
     */
    private boolean is_search;

    /*
     * 告诉后台那些列是需要排序的。 i是一个数组索引,对应的是 columns配置的数组,从0开始
     */
    private int[] order;

    /*
     * 告诉后台列排序的方式, desc 降序 asc升序
     */
    private String order_dir;

    /*
     * columns 绑定的数据源,由 columns.dataOption 定义。
     */
    private String columns_data;

    /*
     * columns 的名字,由 columns.nameOption 定义。
     */
    private String columns_name;

    /*
     * 标记列是否能被搜索,为true代表可以,否则不可以,这个是由 columns.searchableOption 控制
     */
    private String columns_searchable;

    /*
     * 标记列是否能排序,为 true代表可以,否则不可以,这个是由 columns.orderableOption 控制
     */
    private boolean is_orderable;

    /*
     * 标记具体列的搜索条件
     */
    private String columns_search_value;

    /*
     * 特定列的搜索条件是否视为正则表达式, 如果为 true代表搜索的值是作为正则表达式处理,为 false则不是。
     * 注意:通常在服务器模式下对于大数据不执行这样的正则表达式,但这都是自己决定的
     */
    private boolean is_search_regex;

    /*------------------DT自动请求的参数(Sent parameters) end--------------------*/

    /*------------------服务器需要返回的数据(Returned data) begin--------------------*/

    /*
     * 必要。上面提到了,Datatables发送的draw是多少那么服务器就返回多少。
     * 这里注意,作者出于安全的考虑,强烈要求把这个转换为整形,即数字后再返回,而不是纯粹的接受然后返回,这是 为了防止跨站脚本(XSS)攻击。
     */
    // private int draw;

    /*
     * 必要。即没有过滤的记录数(数据库里总共记录数)
     */
    private int recordsTotal;

    /*
     * 必要。过滤后的记录数(如果有接收到前台的过滤条件,则返回的是过滤后的记录数)
     */
    private int recordsFiltered;

    /*
     * 必要。表中中需要显示的数据。这是一个对象数组,也可以只是数组, 区别在于 纯数组前台就不需要用 columns绑定数据,会自动按照顺序去显示
     * ,而对象数组则需要使用 columns绑定数据才能正常显示。 注意这个 data的名称可以由 ajaxOption 的
     * ajax.dataSrcOption 控制
     */
    private List<T> data;

    /*
     * 可选。你可以定义一个错误来描述服务器出了问题后的友好提示
     */
    private String error;

    /*-------------可选参数-----------------*/

    /*
     * 自动绑定到 tr节点上
     */
    private String dt_rowId;

    /*
     * 自动把这个类名添加到 tr
     */
    private String dt_rowClass;

    /*
     * 使用 jQuery.data() 方法把数据绑定到row中,方便之后用来检索(比如加入一个点击事件)
     */
    private Object dt_rowData;

    /*
     * 自动绑定数据到 tr上,使用 jQuery.attr() 方法,对象的键用作属性,值用作属性的值。 注意这个 需要 Datatables
     * 1.10.5+的版本才支持
     */
    private Object dt_rowAttr;

    /*-------------可选参数-----------------*/
    /*------------------服务器需要返回的数据(Returned data) end--------------------*/


    /*
     * 当前页码
     */
    private int page_num =1;

    /*
     * 每页数据
     */
    private int page_size = 10;


    public DataTablePageUtil() {

    }

    public DataTablePageUtil(HttpServletRequest request) {
        //开始的数据行数
        String start = request.getParameter("start");
        //每页的数据数
        String length = request.getParameter("length");
        //DT传递的draw:
        String draw = request.getParameter("draw");

        this.setStart(Integer.parseInt(start));
        this.setLength(Integer.parseInt(length));
        this.setDraw(Integer.parseInt(draw));
        //计算页码
        this.page_num = (Integer.parseInt(start) / Integer.parseInt(length)) + 1;

    }

    public int getDraw() {
        return draw;
    }

    public void setDraw(int draw) {
        this.draw = draw;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public String getSearch() {
        return search;
    }

    public void setSearch(String search) {
        this.search = search;
    }

    public boolean isIs_search() {
        return is_search;
    }

    public void setIs_search(boolean is_search) {
        this.is_search = is_search;
    }

    public int[] getOrder() {
        return order;
    }

    public void setOrder(int[] order) {
        this.order = order;
    }

    public String getOrder_dir() {
        return order_dir;
    }

    public void setOrder_dir(String order_dir) {
        this.order_dir = order_dir;
    }

    public String getColumns_data() {
        return columns_data;
    }

    public void setColumns_data(String columns_data) {
        this.columns_data = columns_data;
    }

    public String getColumns_name() {
        return columns_name;
    }

    public void setColumns_name(String columns_name) {
        this.columns_name = columns_name;
    }

    public String getColumns_searchable() {
        return columns_searchable;
    }

    public void setColumns_searchable(String columns_searchable) {
        this.columns_searchable = columns_searchable;
    }

    public boolean isIs_orderable() {
        return is_orderable;
    }

    public void setIs_orderable(boolean is_orderable) {
        this.is_orderable = is_orderable;
    }

    public String getColumns_search_value() {
        return columns_search_value;
    }

    public void setColumns_search_value(String columns_search_value) {
        this.columns_search_value = columns_search_value;
    }

    public boolean isIs_search_regex() {
        return is_search_regex;
    }

    public void setIs_search_regex(boolean is_search_regex) {
        this.is_search_regex = is_search_regex;
    }

    public int getRecordsTotal() {
        return recordsTotal;
    }

    public void setRecordsTotal(int recordsTotal) {
        this.recordsTotal = recordsTotal;
    }

    public int getRecordsFiltered() {
        return recordsFiltered;
    }

    public void setRecordsFiltered(int recordsFiltered) {
        this.recordsFiltered = recordsFiltered;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getDt_rowId() {
        return dt_rowId;
    }

    public void setDt_rowId(String dt_rowId) {
        this.dt_rowId = dt_rowId;
    }

    public String getDt_rowClass() {
        return dt_rowClass;
    }

    public void setDt_rowClass(String dt_rowClass) {
        this.dt_rowClass = dt_rowClass;
    }

    public Object getDt_rowData() {
        return dt_rowData;
    }

    public void setDt_rowData(Object dt_rowData) {
        this.dt_rowData = dt_rowData;
    }

    public Object getDt_rowAttr() {
        return dt_rowAttr;
    }

    public void setDt_rowAttr(Object dt_rowAttr) {
        this.dt_rowAttr = dt_rowAttr;
    }

    public int getPage_num() {
        return page_num;
    }

    public void setPage_num(int page_num) {
        this.page_num = page_num;
    }

    public int getPage_size() {
        return page_size;
    }

    public void setPage_size(int page_size) {
        this.page_size = page_size;
    }


}

html代码:

<table id="table" class="mdl-data-table product-table m-t-30" cellspacing="0" width="100%">
    <thead>
        <tr>
            <th data-orderable="false" class="col-xs-1">
                <span class="checkbox">
                  <label>
                    <input type="checkbox" value="" id="checkAll">
                    <span class="checkbox-material"></span>
                  </label>
                </span>
            </th>
            <th class="col-xs-2">账号</th>
            <th data-orderable="false" class="col-xs-2">部门</th>
            <th data-orderable="false" class="col-xs-2">岗位</th>
            <th class="col-xs-1">状态</th>
            <th class="col-xs-2">创建时间</th>
            <th class="col-xs-2">修改时间</th>
        </tr>
    </thead>
</table>

js代码:

<script>
    $(function () {
        //初始化表格
        var oTable = $("#table").DataTable({
            "language": {
                "sProcessing":   "处理中...",
                "sLengthMenu":   "显示 _MENU_ 项结果",
                "sZeroRecords":  "没有匹配结果",
                "sInfo":         "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
                "sInfoEmpty":    "显示第 0 至 0 项结果,共 0 项",
                "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
                "sInfoPostFix":  "",
                "sSearch":       "搜索:",
                "sUrl":          "",
                "sEmptyTable":     "表中数据为空",
                "sLoadingRecords": "载入中...",
                "sInfoThousands":  ",",
                "oPaginate": {
                    "sFirst":    "首页",
                    "sPrevious": "上页",
                    "sNext":     "下页",
                    "sLast":     "末页"
                },
                "oAria": {
                    "sSortAscending":  ": 以升序排列此列",
                    "sSortDescending": ": 以降序排列此列"
                },
            },
            ajax: {
                url: "/backend/admin/page",
                type: "POST",
                dataSrc : "data",//这个参数是自己封装的json里面的key
                data: {
                    //args1: "我是固定传参的值,在服务器接收参数[args1]"
                }
            },

            serverSide: true,//开启服务器模式:启用服务器分页
            lengthChange: false,//是否允许用户改变表格每页显示的记录数
            ordering: true,//是否允许用户排序
            paging: true,//是否分页
            pagingType: "full_numbers",//除首页、上一页、下一页、末页四个按钮还有页数按钮
            processing: true,//是否显示处理状态
            scrollCollapse: true,
            searching: false,//是否开始本地搜索
            stateSave: false,//刷新时是否保存状态
            autoWidth: true,//自动计算宽度
            deferRender : true,//延迟渲染
            columns: [
                {data: "id"},
                {data: "account"},
                {data: "departmentName"},
                {data: "stationName"},
                {data: "isLocked"},
                {data: "gmtCreate"},
                {data: "gmtModified"}
            ]
        })
    });
</script>

后台controller分页代码如下:

/**
     * 分页
     * @return
     */
    @RequestMapping(value="/page", method = RequestMethod.POST)
    public @ResponseBody DataTablePageUtil page(HttpServletRequest request)  {
        try{
            DataTablePageUtil<Admin> dataTable = new DataTablePageUtil<Admin>(request);

            PageForm pageForm = new PageForm();
            pageForm.setPage(dataTable.getPage_num());
            pageForm.setRows(dataTable.getPage_size());
            PageInfo<Admin> pageInfo = adminService.pageFind("com.chaofan.www.dao.backend.AdminDao.selectAll",pageForm,null,false);

            dataTable.setDraw(dataTable.getDraw());
            dataTable.setData(pageInfo.getList());
            dataTable.setRecordsTotal((int)pageInfo.getTotal());
            dataTable.setRecordsFiltered(dataTable.getRecordsTotal());
//            JSONObject jsonObject = JSONObject.fromObject(dataTable);
            return dataTable;
        }catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }

其中baseService中的pageFind的接口声明如下:

PageInfo<T> pageFind(String statementKey, PageForm pageForm, Object parameter, Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException;

它的实现baseServiceImpl代码如下:

@Override
public PageInfo<T> pageFind(String statementKey, PageForm pageForm, Object parameter, Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    return baseDao.pageFind(statementKey,pageForm,parameter,isSimplePage);
}

baseDao里的pageFind实现代码如下:

public PageInfo<T> pageFind(String statementKey, PageForm pageForm, Object parameter, Boolean isSimplePage) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    PageHelper.startPage(pageForm.getPage(), pageForm.getRows());
    return new PageInfo(getSqlSession().selectList(statementKey, getParam(parameter)));
}

效果图如下:

171002_klRN_1866080.png

转载于:https://my.oschina.net/junko2013/blog/889315

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值