基于案例解析 bootstrap table 服务端分页与客户端分页
bootstrap table
的分页功能可以分为客户端分页(client
)和服务端(server
)分页两种类型。其中客户端分页会一次性将所有页面的数据加载到前端页面,然后在前端执行数据的分页以及填充。而服务端分页则是根据请求参数中的页码以及每页数据条数分页请求数据,每次只会向数据库请求一页数据。
由于客户端分页会一次性将所有的数据查询回来,因此它只适用于数据量较少的情况,当数据量较大时,一次性查询大量数据耗费大量时间,有时会造成系统崩溃,此时应当使用服务端分页查询数据,这样可以减少数据查询时间,快速响应前端的数据请求。
1、客户端分页
bootstrapTable
在初始化的时候 sidePagination
默认就是使用客户端分页,即默认设置 sidePagination
属性的值为 client
。
下面使用一个简单案例:查询小于20岁的用户并展示在表格上 对客户端分页进行说明
(1)html
代码
//封装查询
<div id="toolbar" class="form-inline">
<input type="number" class="form-control" id="search_age">
<button type="button" class="btn btn-primary" id="btnQuery">
<i class="glyphicon glyphicon-search"></i> 按年龄查询
</button>
</div>
//表格
<table id="table" class="table table-bordered" data-show-refresh="true"
data-show-columns="true">
</table>
(2) js
请求代码
点击 html
中的查询按钮就会触发下面的代码,查询代码此处省略。
$('#table').bootstrapTable({
method:'get',
url:"/user/getUserByAge",//请求路径
pageNumber: 1,//初始化加载第一页
striped: true, //是否显示行间隔色
showRefresh: true,//显示刷新按钮
pagination:true, //是否分页
pageSize:5, //初始化单页记录数
pagination: true, //是否分页
pageList: [5, 10, 20, 30, 50],
search: true, //显示查询框
sidePagination: "client", //使用客户端分页
//下面是封装的请求参数
queryParams:function(params){
var temp = {
//请求参数
age : $('search_age').val()
};
return temp;
},
//将返回的数据封装到表格
columns:[
{
checkbox: true , width: '3%', visible: true //开启复选框
},
{
field: 'id', title: 'id'
},
{
field: 'name', title: '姓名'
},
{
field: 'age', title: '年龄'
},
],
onLoadSuccess: function (json) { //加载成功时执行
console.log("load success");
},
onLoadError: function () { //加载失败时执行
console.log("load fail");
}
});
(3)封装数据的User
对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User{
//User的属性值与上面 data-field 的值一一对应才能自动填充值
private Integer id;
private String name;
private Integer age;
}
(4)Controller
层代码
注意,此处类的访问路径是 /user
,这里使用 mybatis generator
生成相应的数据库访问工具类(UserExample
,UserMapper
)。另外,由于此处的逻辑比较简单,就不多写一层 service
。
@RequestMapping("/getUserByAge")
@ResponseBody
public List<User> getUserByAge(User user , HttpServletRequest request){
UserExample example = new UserExample();
UserExample.Criteria criteria = example.createCriteria();
//查询小于20岁的人
criteria.andAgeLessThan(20);
List<User> result = userMapper.selectByExample(example);
return result;
}
2、服务端分页
服务端分页,需要设置 sidePagination
属性的值为 server
,使用server
分页,则必须要有 url
或者 ajax
选项,以请求后端页面的数据。服务端分页返回的数据必须包含数据总量 total
以及封装数据的列表 rows
2个参数。
此处同样使用上面“查询小于20岁的用户并展示在表格上”的案例对服务端分页进行说明。
html
与上面相同,此处不再赘述。
(1) js
请求代码
和 client
相比,只有 sidePagination
和 queryParams
两个参数需要修改
sidePagination:"server",
queryParams : function(params){
var temp = {
limit:params.limit, // 每页显示数量
offset:params.offset, // SQL语句起始索引
page: (params.offset / params.limit)+1,
age : $('search_age').val()
};
return JSON.stringify(temp);
},
(2)User
与 PageReq
User
类需要继承 Page
类用于封装分页参数, Page
的代码如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageReq{
//每页显示数量
private int limit;
//页码
private int page;
//sql语句开始的索引
private int offset;
}
(3)封装返回给前端的数据实体类 PageRes
代码如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageRes<Bean>{
//封装实体类数据的list
private List<Bean> rows;
//数据总条数
private Integer total;
}
(4)Controller
层 与 UserMapper
代码
从下面的代码可以看出,server
分页返回的数据需要通过 PageRes
进行封装,同时请求参数里面包含着分页请求参数。
@RequestMapping("/getUserByAge")
@ResponseBody
public PageRes<User> getUserByAge(User user , HttpServletRequest request){
//每页显示数据条数
int limit = user.getLimit();
//数据库查询索引起始值
int offset = user.getOffset();
//age参数
int age = user.getAge();
//查询出所有满足条件的数据(当前页面)
List<User> list= userMapper.pageByAge(limit,offset,age);
//封装返回给前端的数据
PageRes<User> result = new PageRes<User>();
result.setRows(list);
result.setTotal(list.size());
return result;
}
需要在 UserMapper 中添加1个方法用于分页查询
//查询出分页查询的数据
@Select("select * from User where 1=1 and age > #{age,jdbcType=INTEGER} limit #{offset,jdbcType=INTEGER} , #{limit,jdbcType=INTEGER}")
List<User> pageByAge(int limit ,int offset ,int age);