Datatables插件的使用(从前台到后台完整流程)

Datatables插件的使用(从前台到后台完整流程)

leo 593 2021-04-10

Datatables插件的使用

1.下载Datatables

官网
中文网

2. 引入jQuery和Datatables的Js

<!-- jQuery 3 -->
<script src="../static/jquery/dist/jquery.min.js"></script>
<!-- DataTables -->
<script src="../static/js/jquery.dataTables.min.js"></script>

为了美观,也把引入CSS引入

<!-- DataTables -->
<link rel="stylesheet" href="../static/css/dataTables.bootstrap.min.css">

3.在前端JS代码中初始化Datatables对象

下面是我已经封装了的方法,可以重复使用。(单独写在一个JS文件中,需要使用就引入)

//函数对象App
var App = function () {
     /*
      * 初始化DataTables
     * */
    var handlerInitDataTables = function (url, columns) {
        var dataTable = $("#dataTable").DataTable({
            "pageLength": 5,
            "ordering": false,
            "lengthChange": false,
            "stateSave": false,
            "processing": true,
            "searching": false,
            "deferRender": true,
            "serverSide": true,
            "ajax": {
                "url": url
            },
            "columns": columns,
            "drawCallback":function ( settings) {
            },
            "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": ": 以降序排列此列"
                }
            }
        });
        return dataTable;
    };
    return{
        //初始化DataTables
        initDataTables:function (url, columns) {
            return handlerInitDataTables(url,columns);
        }
    }
}();

上面表明Datatables是ID为dataTable的表格元素,
方法参数1:url是请求后台的地址,方法参数2:columns是定义每列展示什么数据。
所以,需要现在jsp中定义一个<table>元素,且id为上面指定的id。

<table id="dataTable" class="table table-hover">
    <thead>
    <tr>
        <th>软件名称</th>
        <th>APK名称</th>
        <th>软件大小(单位:M)</th>
        <th>所属平台</th>
        <th>所属分类(一、二、三级分类)</th>
        <th>状态</th>
        <th>下载次数</th>
        <th>最新版本号</th>
        <th>操作</th>
    </tr>
    </thead>
    
    <tbody>
    </tbody>
</table>

注意:定义表格时,最好完整定义即有<thead><tbody>元素。
接着需要在文件的js代码中调用上面自定义的初始化方法(initDataTables)

var dataTable;
$(function () {
    //设置每列显示什么数据
    var columns = [
        {"data": "softwarename"},
        {"data": "apkname"},
        {"data": "softwaresize"},
        {"data": "floatformid.valuename"},
        {"data": "categorylevel.categoryname"},
        {"data": "status.valuename"},
        {"data": "downloads"},
        {"data": "appversion.versionno"},
        {
            "data": function (row, type, val, meta) {
                return '<a href="/app/info?id=' + row.id + '"class="btn btn-default btn-sm" onclick="#"><i class="fa fa-search">查看</i></a>';
            }
        }
    ];
    //初始化DataTables
    dataTable = App.initDataTables("${pageContext.request.contextPath}/app/page",columns);
}

至此,前端基本搞定,后端需要接收到Datatables传来的参数,然后返回相应的数据即可。

4. 在后台接收参数并返回数据

Controller层接收数据

@Controller
@RequestMapping("app")
public class AppInfoController {
    @Autowired
    private AppInfoService appInfoService;
    
    /**
     * 分页查新app信息
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "page", method = RequestMethod.GET)
    public PageInfo<AppInfo> page(HttpServletRequest request, AppInfo appInfo){
        //DataTables参数
        String draw = request.getParameter("draw");
        String start = request.getParameter("start");
        String length = request.getParameter("length");
        int intDraw = draw == null ? 0 : Integer.parseInt(draw);
        int intStart = start == null ? 0 : Integer.parseInt(start);
        int intLength = length == null ? 5 : Integer.parseInt(length);
        //封装 DataTables 需要的数据
        return appInfoService.page(intDraw, intStart, intLength, appInfo);
    }
}

可以看到,Datatables传递的参数主要有draw:就是一个标识,前端传的值是什么就返回什么。start:每页的开始索引。length:每页记录的数量(可以通过在初始化的时候设置pageLength改变)。另外方法上加了@ResponseBody注解,表明返回的是JSON格式数据。我在Maven依赖里添加了Jackson的包,所以Spring可以帮我们将对象转JSON字符串。

依赖如下:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

Service接口:

public interface AppInfoService {
    /**
     * 分页查询
     * @param draw
     * @param start 开始记录
     * @param length 每页大小
     * @param appInfo 封装查询条件
     * @return
     */
    PageInfo<AppInfo> page(int draw, int start, int length, AppInfo appInfo);
}

Service实现类:

@Service
@Transactional(readOnly = true)
public class AppInfoServiceImpl implements AppInfoService {
    @Autowired
    private AppInfoMapper appInfoMapper;
    
    public PageInfo<AppInfo> page(int draw, int start, int length, AppInfo appInfo) {
        PageInfo<AppInfo> pageInfo = new PageInfo<>();
        Map<String,Object> params = new HashMap<>();
        params.put("start",start);
        params.put("length",length);
        params.put("pageParams",appInfo);
        List<AppInfo> appInfos = appInfoMapper.page(params);
        //由于可能有查询条件查询,所以须查询出记录总数
        int count = appInfoMapper.count(params);
        pageInfo.setData(appInfos);
        pageInfo.setDraw(draw);
        pageInfo.setRecordsTotal(count);
        pageInfo.setRecordsFiltered(count);
        pageInfo.setError("");
        return pageInfo;
    }
}

Mapper(DAO):

public interface AppInfoMapper extends Mapper<AppInfo> {

    List<AppInfo> page(Map<String,Object> param);
}

PageInfo类:

/**
 * @program: app-store
 * @description: 分页数据传输对象
 * @author: Leo
 * @create: 2019-08-07 13:59
 **/
public class PageInfo<T> implements Serializable {
    private int draw; //回传draw
    private int recordsTotal; //记录总数
    private int recordsFiltered; //被过滤记录数
    private List<T> data; //数据
    private String error; //错误信息

    //Getter And Setter
}

前面涉及的类和接口的说明:

  1. AppInfo: 实体类。
  2. PageInfo:分页信息类(里面封装了Datatables所需的数据)。
  3. Mapper<AppInfo>:Mybatis通用mapper接口,可以简化单表操作。

之后在对应的mapper文件中写SQL语句就行了。

带条件查询

很多时候需要带条件查询,也很简单。设置查询参数,重新加载Datatables即可:

//搜索
function search() {
    var softwarename = $("#softwarename").val();
    var status = $("#status").val();
    var floatformid = $("#floatformid").val();
    var categorylevel1 = $("#categorylevel1").val();
    var categorylevel2 = $("#categorylevel2").val();
    var categorylevel3 = $("#categorylevel3").val();
    //查询参数
    var param = {
        "softwarename":softwarename,
        "status.id":status,
        "floatformid.id":floatformid,
        "categorylevel1.id":categorylevel1,
        "categorylevel2.id":categorylevel2,
        "categorylevel3.id":categorylevel3
    };
    if (softwarename === ''){
        delete param.softwarename;
    }
    if (status === ''){
        delete param["status.id"];
    }
    if (floatformid === ''){
        delete param["floatformid.id"];
    }
    if (categorylevel1 === ''){
        delete param["categorylevel1.id"];
    }
    if (categorylevel2 === ''){
        delete param["categorylevel2.id"];
    }
    if (categorylevel3 === ''){
        delete param["categorylevel3.id"];
    }
    //console.log(param);
    if (param !== {}){
        //设置参数,重新加载
        dataTable.settings()[0].ajax.data = param;
        dataTable.ajax.reload();
    }
}

上面的dataTable是之前初始化的时候保存的Datatables对象。

效果

使用效果