Mybatis pageHelper 配合jquery DataTable实现分页效果

    Hibernate中集成了分页的后台方法,Mybatis中没有,想要方便的使用分页功能,就必须使用牛人开发的pageHelper插件。前台配合jquery的datatable或者jqGrid实现列表效果,本次使用的是datatable。

首先想看官方详细文档请看,非常全面

Datatables 中文网

另外我找到一片非常详细的介绍datatable的文章

Jquery DataTable基本使用 - xiashengwang - 博客园

    一 . pagehelper配置及使用介绍

    1.我用的maven工程,首先引入依赖

<!--分页-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.1</version>
        </dependency>

2.在mybatis配置文件spring-mybatis.xml中配置

<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->    
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">    
     <property name="dataSource" ref="dataSource" />    
     <!-- 自动扫描mapping.xml文件 -->    
     <property name="mapperLocations">
         <array>
             <value>classpath:com/zhuhuixin/webmana/dao/mapper/xml/*.xml</value>
             <value>classpath:com/zhuhuixin/webshow/dao/mapper/xml/*.xml</value>
         </array>
     </property>
     <property name="plugins">  //在此处配置
         <array>
             <bean class="com.github.pagehelper.PageHelper">
                 <property name="properties">
                     <value>
                         dialect=mysql
                         reasonable=true
                     </value>
                 </property>
             </bean>
         </array>
     </property>
 </bean>

3.datatable将会默认发送给你draw,start(开始条数),length(每页条数),但pagehelper要的参数为当前页码和每页条数,所以要将start处理一下,currentPage=start/length+1。

    设置完PageHelper.startPage(currentPage,pageSize)后的第一个使用查询方法,mybatis会自动使用分页功能,查询出的list就是分页后的值

// 获取用户列表
@ResponseBody
@RequestMapping(value = "listUser", produces = "text/plain;charset=UTF-8")
public String listUser(Integer start,Integer length,HttpServletRequest req) {
    List<TSystemUser> list = new ArrayList<TSystemUser>();
    Map resultMap = new HashMap();
    PageHelper.startPage((start/length+1),length); //第一个参数为当前页码,第二个为每页的条数
    try {
        list = userService.findUserByCondition(userParam);  //之后的第一个查询方法
        Page<TSystemUser> pageBean = new Page<TSystemUser>(new PageInfo<TSystemUser>(list),req);
        //如果直接则自动去掉为null的字段,不想去掉需要这样处理
        return JSON.toJSONString(pageBean, SerializerFeature.WriteMapNullValue);
    } catch (Exception e) {
        e.printStackTrace();
        resultMap.put("success","false");
        resultMap.put("msg",e.getMessage());

    }
    return JSON.toJSONString(resultMap);
}

    PageInfo类说明

public class PageInfo<T> implements Serializable {  
    private static final long serialVersionUID = 1L;  
    //当前页  
    private int pageNum;  
    //每页的数量  
    private int pageSize;  
    //当前页的数量  
    private int size;  
  
    //由于startRow和endRow不常用,这里说个具体的用法  
    //可以在页面中"显示startRow到endRow 共size条数据"  
  
    //当前页面第一个元素在数据库中的行号  
    private int startRow;  
    //当前页面最后一个元素在数据库中的行号  
    private int endRow;  
    //总记录数  
    private long total;  
    //总页数  
    private int pages;  
    //结果集  
    private List<T> list;  
  
    //前一页  
    private int prePage;  
    //下一页  
    private int nextPage;  
  
    //是否为第一页  
    private boolean isFirstPage = false;  
    //是否为最后一页  
    private boolean isLastPage = false;  
    //是否有前一页  
    private boolean hasPreviousPage = false;  
    //是否有下一页  
    private boolean hasNextPage = false;  
    //导航页码数  
    private int navigatePages;  
    //所有导航页号  
    private int[] navigatepageNums;  
    //导航条上的第一页  
    private int navigateFirstPage;  
    //导航条上的最后一页  
    private int navigateLastPage;  
  
    public PageInfo() {  
    }  
  
    /** 
     * 包装Page对象 
     * 
     * @param list 
     */  
    public PageInfo(List<T> list) {  
        this(list, 8);  
    }  
  
    /** 
     * 包装Page对象 
     * 
     * @param list          page结果 
     * @param navigatePages 页码数量 
     */  
    public PageInfo(List<T> list, int navigatePages) {  
        if (list instanceof Page) {  
            Page page = (Page) list;  
            this.pageNum = page.getPageNum();  
            this.pageSize = page.getPageSize();  
  
            this.pages = page.getPages();  
            this.list = page;  
            this.size = page.size();  
            this.total = page.getTotal();  
            //由于结果是>startRow的,所以实际的需要+1  
            if (this.size == 0) {  
                this.startRow = 0;  
                this.endRow = 0;  
            } else {  
                this.startRow = page.getStartRow() + 1;  
                //计算实际的endRow(最后一页的时候特殊)  
                this.endRow = this.startRow - 1 + this.size;  
            }  
        } else if (list instanceof Collection) {  
            this.pageNum = 1;  
            this.pageSize = list.size();  
  
            this.pages = this.pageSize > 0 ? 1 : 0;  
            this.list = list;  
            this.size = list.size();  
            this.total = list.size();  
            this.startRow = 0;  
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;  
        }  
        if (list instanceof Collection) {  
            this.navigatePages = navigatePages;  
            //计算导航页  
            calcNavigatepageNums();  
            //计算前后页,第一页,最后一页  
            calcPage();  
            //判断页面边界  
            judgePageBoudary();  
        }  
    }  
  
  
.......  
}  

    本来查询完需要用 PageInfo data=new PageInfo<>(list)封装就行,但是我们要返回给datatable合适的值,所以我将data二次封装。直接返回pagebean则为datatable需要接受的参数。

    这里要注意不要使用JSON.toJSONString(pagebean),因为此方法默认值为null的字段被自动去除,没有字段前台的datatable就会报错。用使用JSON.toJSONString(pageBean,SerializerFeature.WriteMapNullValue)才能正常返回。

封装类:

public class Page<T> {

    /**
     * <p>Title: </p>
     * <p>Description: 构造函数,传入一个com.github.pagehelper.PageInfo对象</p>
     *
     * @param pageInfo
     */
    public Page(PageInfo<T> pageInfo,HttpServletRequest req) {
        try {
            this.setDraw(req.getParameter("draw"));//从request中获取的draw在发回去
            this.setPageSize(pageInfo.getPageSize());
            this.setRecordsTotal(pageInfo.getTotal());
            this.setRecordsFiltered(pageInfo.getTotal());
            this.setData(pageInfo.getList());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 当前页
    private String draw;
    // 总页数
    private Integer total;
    // 每页显示多少
    private Integer pageSize;
    // 总记录数
    private long recordsTotal;
    private long recordsFiltered;
    // 记录
    private List<T> data;

    public String getDraw() {
        return draw;
    }

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

    public Integer getTotal() {
        return total;
    }

    public void setTotal(Integer total) {
        this.total = total;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public long getRecordsTotal() {
        return recordsTotal;
    }

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

    public long getRecordsFiltered() {
        return recordsFiltered;
    }

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

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

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

二 . 前台datatable的配置及使用

    要注意前台传给后台的参数和需要接受的参数。

前端传递参数:  
columns[0][data]    0  
columns[0][name]      
columns[0][orderable]    true  
columns[0][search][regex]    false  
columns[0][search][value]      
columns[0][searchable]    true  
columns[1][data]    1  
columns[1][name]      
columns[1][orderable]    true  
columns[1][search][regex]    false  
columns[1][search][value]      
columns[1][searchable]    true  
columns[2][data]    2  
columns[2][name]      
columns[2][orderable]    true  
columns[2][search][regex]    false  
columns[2][search][value]      
columns[2][searchable]    true  
columns[3][data]    3 // data[3]  
columns[3][name]      
columns[3][orderable]    true         //可以排序  
columns[3][search][regex]    false         //搜索内容不支持正则表达式  
columns[3][search][value]    //搜索的内容  
columns[3][searchable]    true  //可以被搜索  
draw    1    //浏览器cache的编号,递增不可重复  
length    10 //预读长度= 预读页数*每页行数  
order[0][column]    0  //按第一列排序  
order[0][dir]    asc  
search[regex]    false //搜索内容不支持正则表达式  
search[value]    //输入的搜索的内容  
start    0//起始位子,如第一页就从  
  
返回值格式:  
{  
  "draw": 10, //浏览器cache的编号,递增不可重复  
  "recordsTotal": 57, //数据总行数  
  "recordsFiltered": 57, //数据总行数  
  "data": [  
    [  
      "Cara",  
      "Stevens",  
      "Sales Assistant",  
      "New York",  
      "6th Dec 11",  
      "$145,600"  
    ],  
    [  
      "Shou",  
      "Itou",  
      "Regional Marketing",  
      "Tokyo",  
      "14th Aug 11",  
      "$163,000"  
    ]  
  ]  
} 

    我封装的pagebean符合接受参数要求,所以直接开始使用。如果不封装,想自定义设置接受参数,需要加入dataSrc(下面有示例),依次把draw,recordstotal,recordsfiltered,data设置一遍(注意draw,recordstotal,recordsfiltered,data必须为json的一级子集,不然无效),最后返回json.data

    栗子:

var tableObj = null;
var tableColumns = [
      			{data:"userId",className:'text-c',title: "<input type='checkbox' name='checklist' id='checkall' />", width:10},
      			{data:"loginName", title:"登录名"},
      			{data:"userName", title:"姓名"},
      			{data:"userGender", title:"性别"},
      			{data:"userPhone", title:"电话"},
      			{data:"userStatus", title:"是否启用"},
      			{data:"userId", title:"操作", width:100}
      		 ];

tableObj =  $('.table-sort').DataTable({
    serverSide:true,//设为true为后台处理分页
    searching:false,
    ordering:false,
    processing:true,
    stateSave:false,
    autoWidth:false,
    ajax:{
        url:"listUser.do",
        type:"post",
        data:function(d){
           // d.currentPage= d.start;  //可以改变往前台传的参数名
          //  d.pageSize= d.length;
            return $.extend( {}, d, {  //往前台传自定义参数要这么写
                "info": $('#info').val(),
                "orgId": $('#orgId').val(),
                "roleId": $('#roleId').val(),
                "userLimit": $("select[name='userLimit']").val()
            });
        },
        /*dataSrc: function (json) { // 想处理返回参数时这样做,因为我已经封装了返回参数,这里就不需要了
            /!*console.log(json)
            json.recordsTotal=json.total;
            json.recordsFiltered=json.total;
            json.data=json.list;*!/
            return json.data;
        },*/
    },

    columns:tableColumns,
    columnDefs: [
         {
            //第一列checkbox
            targets: 0,
            render: function(data, type, row, meta) {
                return '<input type="checkbox" name="checklist" value="' + data + '" />'
            }
         }
     ]
});

recordstotal,recordsfiltered为总记录数,在pageInfo里面自带,draw为前台传给后台的,后台要原样返回,不然分页效果会出错。

    总之用起来有点麻烦,耐心研究吧,配置好后还是很好用的

-----------------------------------------------------------------------------------------------------

补充:

最近又用到了这个插件,有一些问题弄了半天才解决,来记录一下

1.配置参数问题:旧版本配置参数名字都比较奇怪,前面总有类似“a”,"b"之类的前缀,比如‘autoWidth’成了‘bAutoWidth’,不过新版本的名字都正常了,直接写‘autoWidth’就行了,不要被某些文档搞晕;

2.如果数据源不直接用ajax请求,而是用参数data参数渲染,则在data中传入对象数组即可,注意不是json字符串

var tableObj =  $('.table-right').DataTable({
			ordering:false,
			paging: false,//开启表格分页
			autoWidth:false,
			data:[{"GROUPID":"11","GROUPNAME":"名字一"},{"GROUPID":"22","GROUPNAME":"名字二"}],
			columns:[
				{data:"userId",className:'text-c',title: "<input type='checkbox' name='checklist' id='checkall2' />", width:10},
				{data:"GROUPID", title:"营业厅编码"},
				{data:"GROUPNAME", title:"营业厅名称"}
			],
			columnDefs: [
				{
					//第一列checkbox
					targets: 0,
					render: function(data, type, row, meta) {
						return '<input type="checkbox" name="checklist" class="checklist2" value="' + row.GROUPID + '" />'
					}
				}
			],
			
		});

3.重新加载表格

function reloadTable() {
	//参数1:当服务器返回数据并重绘完毕时执行此回调方法,回调方法返回的是服务器返回的数据
	//参数2:重置(默认或者设置为true)或者保持分页信息(设置为false)
	tableObj.ajax.reload(function(data){}, false);
	
}

4.换url重新加载

table.ajax.url( 'newData.json').load();

5.清空表格数据

tableObj1.clear().draw()

6.销毁表格

tableObj1.destroy(false)

false为销毁数据但html还在,true直接连html也销毁了,慎用true

ps:弹出报错问题

有时候返回的数据可能为空或者直接缺失某个字段,就会弹出 DataTables warning: table id=DataTables_Table_0 - Requested unknown parameter 'xxx' for row 0.类似的错误,这样在

tableColumns里面设置一下默认值就行,加个defaultContent
var tableColumns = [
		{data:"deal_date", title:"用户名","defaultContent": ""},
		{data:"xxx", title:"东回镇","defaultContent": ""},

	];

这样缺失字段或者数据就不会报错了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆趣编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值