使用bootstrap table和SpringBoot,mysql实现后台管理数据表格的后端分页

最近在做后台管理系统,在数据表格展示选择dataTable和bootstrap table上浪费了很多时间,刚开始使用dataTable,但是后面发现使用ajax异步请求填充表格数据十分复杂,于是转向了bootstrap table,bootstrap table在向后端传递分页参数上比datatable更简单明了,也更容易上手开发。首先贴出实现界面。

前端引入css,js就不赘述了,在这主要记录一下boostrap-table js书写以及后端代码的书写。要启用bootstrap-table,只需要在前端界面,添加一个table标签,然后添加data-toggle=“table”属性即可,下方是我自己添加的表格上方的搜索栏。

js文件,主要用于初始化bootstrap-table以及定义向后端传递的分页参数。 queryParams是自带就有的,当设置好了分页显示第一页,每页8条数据,当设置了url请求路径后,可以打开f12浏览器调试窗口,可以看到其实bootstrap-table默认就是发送offset偏移量(跳过的条数)和limit查询条数的,但是如果需要自定义向后台传参,就需要加上queryParams这段函数代码块。简而言之,如果只需要向后端传递offset和limit两个参数,可以省略queryParams这段函数代码块,发送的get请求已经包含了offset=0&limit=8参数。

/*bootstrap-table初始化*/
$("#user-table").bootstrapTable({
    url: "/api-staff/v1/staff/listRange",
    striped: true,//设置为 true 会有隔行变色效果
    //showToggle: "true",//是否显示 切换试图(table/card)按钮
    pagination: true,
    sidePagination: "server",
    pageNumber: 1,
    pageSize: 8,
    queryParams: function (params) { //这里的params是table提供的,传到后台
        return {
            offset:params.offset,   //跳过多少条数
            limit:params.limit      //找多少条数据
        }
    },
    responseHandler: function (result) {
        return {
            "total": result.total,   //查询出来的总数
            "rows": result.data  //数据
        }
    },
    columns: [
        {
            width: '40px',
            field: "checkAll",
            title: '<input type="checkbox" id="checkAll">',
            align: "center",
            valign: "middle",
            formatter: checkFormatter
        }, {
            field: "staffId",
            title: "工号",
            align: "center",
            valign: "middle"
        }, {
            field: "name",
            title: "姓名",
            align: "center",
            valign: "middle"
        }, {
            field: "depetId",
            title: "部门",
            align: "center",
            valign: "middle"
        }, {
            field: "phone",
            title: "手机号",
            align: "center",
            valign: "middle"
        }, {
            field: "idNum",
            title: "身份证号",
            align: "center",
            valign: "middle"
        }, {
            field: "idCardNum",
            title: "IC卡号",
            align: "center",
            valign: "middle"
        }, {
            width: "90px",
            field: "staffId",
            title: "人脸数量",
            align: "center",
            valign: "middle"
        }, {
            field: "gmtCreate",
            title: "创建时间",
            align: "center",
            valign: "middle"
        }, {
            field: "imgPath",
            title: "照片",
            align: "center",
            valign: "middle",
        }, {
            field: "opt",
            title: "操作",
            align: "center",
            valign: "middle",
            formatter: optFormatter
        }
    ]
});
/*当点击编辑时,弹出编辑模态框*/
$("#user-table").on("click", 'a[data-type="edit"]', (e) => {
    $("#modal-editUser").modal("show")
});
/*当点击删除时,弹出删除的模态框*/
$("#user-table").on("click", 'a[data-type="remove"]', (e) => {
    $('#modal-deleteUser').modal('show');
});

/*生成编辑删除选项*/
function optFormatter(value, row, index) {
    let re = '';
    re += '<a href="javascript:void(0)" title="编辑" data-type="edit"><i class="far fa-edit"></i></a>&nbsp&nbsp&nbsp&nbsp';
    re += '<a href="javascript:void(0)" title="删除" data-type="remove"><i class="far fa-trash-alt"></i></a>';
    return re;
};

/*生成勾选框*/
function checkFormatter() {
    let re = '<input type="checkbox" id="checkList">';
    return re;
}

然后事情就变得简单了,后端只需要接收前端传过来的offset和limit两个参数,然后用limit关键字向实体类数据表查询即可。但是需要注意一点,查出的实体类是一个8个长度的集合,但是bootstrap-table还需要后端返回一个当前数据表的总数据条数,比如查询User表的前8条数据,select * from user limit 0,8;这是一个长度为8的User集合,也需要返回User表的总长度total,也就是select count(*)from user;bootstrap-table才能根据数据表当前的总条数来分页。

responseHandler这个函数用于处理后端响应的数据,result是后端返回的数据,在这也就是map,“total”表示查询出来的总数,即上面说的需要返回User表的条数,“rows”是返回的实体类原数据data。

responseHandler: function (result) {
        return {
            "total": result.total,   //查询出来的总数
            "rows": result.data  //数据
        }
    },

接下来我们直接看后端代码。

Controller控制器代码

 @Resource
    IStaffService service;

    /**
     * 根据用户输入页码返回员工信息到页面
     * @return
     */
    @RequestMapping("/listRange")
    public Map<String,Object> getPage(@RequestParam(value = "offset",required = true)Integer offset,
                                         @RequestParam(value = "limit",required = true)Integer limit){

        return service.getPage(offset,limit));

Service层代码

@Service
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {

    @Resource
    StaffMapper mapper;

    @Override
    public Map<String, Object> getPage(Integer offset, Integer limit) {
        Map<String,Object> resultMap = new HashMap();
        List<Staff> staffList = null;
        Integer total = 0;
        try {
            staffList = mapper.getPage(offset,limit);
            total = mapper.findAllCount();
        }catch (Exception e){
            e.printStackTrace();
        }
        resultMap.put("data",staffList);
        resultMap.put("total",total);
        return resultMap;
    }
}

Mapper代码

@Repository
public interface StaffMapper extends BaseMapper<Staff> {
    List<Staff> getPage(@Param("offset") Integer offset, @Param("limit") Integer limit);

    Integer findAllCount();
}

XML接口文件,BaseResultMao是mybatis-plus generator自动生成的,这里只是写了两个查询。

<mapper namespace="cn.thinvent.api.staff.mapper.StaffMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="cn.thinvent.api.staff.model.Staff">
        <id column="id" property="id" />
        <result column="staff_id" property="staffId" />
        <result column="name" property="name" />
        <result column="depet_id" property="depetId" />
        <result column="phone" property="phone" />
        <result column="id_num" property="idNum" />
        <result column="id_card_num" property="idCardNum" />
        <result column="gmt_create" property="gmtCreate" />
        <result column="modified" property="modified" />
    </resultMap>

    <select id="getPage" resultMap="BaseResultMap">
        select * from staff LIMIT #{offset },#{limit}
    </select>

    <select id="findAllCount" resultType="java.lang.Integer">
        select count(*) from staff;
    </select>


</mapper>

实体类,切记js文件中table的Columns里的fields需要和实体类的属性名对应一致,不然BootStrap-table不能自动装填数据。

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("staff")
public class Staff implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 人员编号,注册时必填项
     */
    @TableField("staff_id")
    private String staffId;

    /**
     * 员工姓名
     */
    @TableField("name")
    private String name;

    /**
     * 员工部门
     */
    @TableField("depet_id")
    private String depetId;

    /**
     * 员工手机号
     */
    @TableField("phone")
    private String phone;

    /**
     * 员工身份证号,非必填项
     */
    @TableField("id_num")
    private String idNum;

    /**
     * IC卡号,非必填项
     */
    @TableField("id_card_num")
    private String idCardNum;

    /**
     * 人员创建时间,自动生成
     */
    @TableField("gmt_create")
    private LocalDateTime gmtCreate;

    /**
     * 修改更新时间
     */
    @TableField("modified")
    private LocalDateTime modified;

    /**
     * 人脸照片路径
     */
    @TableField("img_path")
    private String imgPath;
}

大致实现方式就这些,实现以后可以将请求完整路径在浏览器输入,测试一下。比如我这个路径显示的数据是这样的。我这里结果是装在R类的,所以返回的格式可能跟你们不太一样,根据自己返回的结果确定responseHandler里的“total”和“rows”即可。

此时打开后台网页,刷新就可以显示数据了,而且是使用后端分页来查询的,这一点打开F12,在点击下一页时,会发送请求下一页的请求,可以印证是后端分页。

实现这个功能耗费了两天的学习,从dataTable到BootStrap-table,自己摸索着学习,遇到了很多问题,欢迎大家一起来交流学习。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页