JavaWeb从新手到入门(四)Spring Mybatis使用pageHelper实现物理分页

参考:MySql从一窍不通到入门(二)大数据量分页查询方法

一、分页

对JavaWeb来说,分页是十分常见的一种需求,一般来说数据的项目大于单次可显示的条目,因此当查询时需要对查询得到的结果进行分页显示。

二、MyBtais分页方法的分类

Mybatis被称为半自动化的ORM框架,因为相比hibernate而言,其对SQL操作的屏蔽更加浅层表面,Mybatis将SQL操作提取并容纳于Mapper.xml文件中,新添加的操作需要使用者写出SQL语句,因此对于分页是功能较弱。

MyBatis分页的方法按照SQL的执行方式来分为两种:

1. 内存分页,也就是假分页。本质是查出所有的数据然后根据游标的方式截取需要的记录。如果数据量大,开销大和内存溢出。

2. 物理分页,也就是查询执行的SQL语句为添加分页指令后的语句,这种情况下Mybatis的分页不再是系统的性能瓶颈。

按照实现方式来说,物理分页又可以分为自定义SQL和实现拦截器两种,下面分别介绍内存分页和物理分页的实现方法。

三、MyBatis分页方法的实现

3.1 内存分页

优点:实现简单,不需要添加额外代码

缺点:大数据情况下性能差。

内存分页的实现通过利用自动生成的example类,加入mybatis的RowBounds类,在调用的接口中添加给类的参数,示例代码如下:

1. 添加rowBounds参数

    @RequestMapping("/itemlist1/{pageNum}")
    @ResponseBody
    private List getItemBypage1(@PathVariable Integer pageNum){
        TbItemExample example = new TbItemExample();
        RowBounds rowBounds = new RowBounds(0, 5);
        TbItemExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("Id desc");//设置排序方式
        return itemMapper.selectByExampleEx(example, rowBounds);
    }

2. 实现冗余查询方法

此处的selectByExampleEx为自定义方法,与selectByExample一致(传入的RowBounds参数由Mybatis自行处理,不需要在SQL语句中做出反应)。

List selectByExampleEx(TbItemExample example, RowBounds rowBounds);
这样实现的分页在大数据情况下需要查询出所有结果后进行截取,因此性能较差,不常使用。

JavaWeb从新手到入门(四)Spring Mybatis使用pageHelper实现物理分页_第1张图片

3.2 自定义SQL

优点:SQL查询效率优化余地大,使用方便

缺点:要为每一个需要分页特性的类添加代码,工作量大且不灵活

自定义SQL的实现需要在真正执行的SQL语句上修改,使传入的参数中增加分页上下限的功能,本次采用修改Example对象的方法进行

1.修改Example对象

public class TbItemExample {
    protected String orderByClause;

    protected boolean distinct;

    public int start;

    public int limit;

    public int getStart() { return start;}

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

    public int getLimit() { return limit;}

    public void setLimit(int limit) { this.limit = limit;}
    ...
}

2. 修改SQL语句

添加Start和limit属性后对selectByExample语句对应的SQL语句进行修改:

3. 添加查询属性

添加了start和limit不为0时的分页处理,确保分页正确完成,使用时在Controller中设置属性即可:

@RequestMapping("/itemlist2/{pageNum}")
    @ResponseBody
    private List getItemBypage2(@PathVariable Integer pageNum){
        TbItemExample example = new TbItemExample();
        example.setStart(0);
        example.setLimit(5);
        example.setOrderByClause("Id desc");//设置排序方式
        return itemMapper.selectByExample(example);
    }
查询能够达到预期效果:

JavaWeb从新手到入门(四)Spring Mybatis使用pageHelper实现物理分页_第2张图片

3.3 拦截器

优点:使用方便,不存在分页上额外的性能瓶颈。

缺点:引入开源库干扰项目的稳定性,性能难以优化。

Mybatis中使用的拦截器可以类比Spring中的AOP概念,通过拦截器获取SQL语句,然后对SQL语句进行修改之后再进行下一步查询,这样的方法使用户使用起来更加简洁清晰,但是也需要注意,这样的话SQL优化就只能依靠封装的开源库的内部实现了(毕竟SQL语句修改的地方被开源库隔离了)。常用的开源库是pageHleper,项目地址: Mybatis_PageHelper

插件的使用分为如下的步骤:

1. 在POM中引入依赖:

            
                com.github.pagehelper
                pagehelper
                3.7.5
            
作者是个很勤奋的人,目前已经更新到5.x,本博客中使用了3.7.5无误,其余需要摸索下(5.x之后主类名和参数定义发生变化)。

2. 在Spring-mybatis配置文件中添加插件

	
    
        
        
        
        
        
            
                
                    
                        
                                    
           		    
                        
                    
                
            
        
    

由于本例中将mybatis与Spring整合到了一起,所以pageHelper的依赖以bean的方式配置在Spring中,插件还提供了作为Mybatis配置的一种方式。配置中主要的依赖项参见作者说明:使用方法

3. 在使用处添加开始代码

在Controller中添加代码如下:

@RequestMapping("/itemlist/{pageNum}")
    @ResponseBody
    private List getItemByPage(@PathVariable Integer pageNum) {
        PageHelper.startPage(pageNum,10);
        TbItemExample example = new TbItemExample();
        List list = itemMapper.selectByExample(example);
        return list;
    }
其中PageHelper.startPage(pageNum,10);指定下一句执行的SQL具备分页特性(只有紧接着的下一句才有效)。

执行结果发现已经达到了分页的目的:

JavaWeb从新手到入门(四)Spring Mybatis使用pageHelper实现物理分页_第3张图片


你可能感兴趣的:(JavaWeb)