springboot结合mybatis使用pageHelper插件进行分页查询

1、pom相关依赖引入

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>

2、application配置

# MyBatis
mybatis:
    #数据库映射对象包路径
    type-aliases-package: com.example.springbootpagehelper.domain
    #mapper对应xml路径
    mapper-locations: classpath:/mybatis/*.xml
    #sql打印配置
    configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# PageHelper分页插件配置
pagehelper:
    #分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。
    helper-dialect: mysql
    #分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
    reasonable: true
    #支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。
    support-methods-arguments: true
    #为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum。
    params: count=countSql

3、代码编写分页查询

  @Autowired
    private UserService userService;

    @RequestMapping(value = "listUser")
    public List<User> listUser(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageNum) {
        //分页查询,包括分页和总数查询,第三个参数是控制是否计算总数,默认是true,true为查询总数,分页效果只对其后的第一个查询有效。
        PageHelper.startPage(pageNo, pageNum);
        //有分页
        List<User> userList = userService.listUser();
        //没分页
        List<User> users = userService.listUser();

        return userList;
    }

对返回结果用PageInfo进行封装

  @RequestMapping(value = "pageInfoUser")
    public PageInfo<User> pageInfoUser(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageNum) {
        //分页查询,包括分页和总数查询,第三个参数是控制是否计算总数,默认是true,true为查询总数,分页效果只对其后的第一个查询有效。
        PageHelper.startPage(pageNo, pageNum);

        PageInfo<User> userPageInfo = userService.pageInfoUser();

        return userPageInfo;
    }

 UserService类

@Override
public PageInfo<User> pageInfoUser() {
     return new PageInfo<>(userMapper.selectUserPage());
}

4、分页安全性问题

PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。

一般只要保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。

如果代码在进入 Executor 前发生异常,就会导致线程不可用,导致 ThreadLocal 参数被错误的使用。

下面这样的代码是不安全的用法:

PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

这种情况下由于 param1 存在 null 的情况,就会导致 PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了错误的分页。

应该写成下面这个样子:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

或者可以手动清理 ThreadLocal 存储的分页参数,如下所示:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    try{
        list = countryMapper.selectAll();
    } finally {
        PageHelper.clearPage();
    }
} else {
    list = new ArrayList<Country>();
}

源码参照:【Springboot使用PageHelper插件进行分页查询

猜你喜欢

转载自www.cnblogs.com/kingsonfu/p/10389021.html