1、pom相关依赖引入

org.springframework.boot

spring-boot-starter-web

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.0.0

mysql

mysql-connector-java

runtime

org.springframework.boot

spring-boot-starter-test

test

com.github.pagehelper

pagehelper-spring-boot-starter

1.2.5

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、代码编写分页查询

@AutowiredprivateUserService userService;

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

PageHelper.startPage(pageNo, pageNum);//有分页

List userList =userService.listUser();//没分页

List users =userService.listUser();returnuserList;

}

对返回结果用PageInfo进行封装

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

PageHelper.startPage(pageNo, pageNum);

PageInfo userPageInfo =userService.pageInfoUser();returnuserPageInfo;

}

UserService类

@Overridepublic PageInfopageInfoUser() {return new PageInfo<>(userMapper.selectUserPage());

}

4、分页安全性问题

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

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

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

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

PageHelper.startPage(1, 10);

Listlist;if(param1 != null){

list=countryMapper.selectIf(param1);

}else{

list= new ArrayList();

}

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

应该写成下面这个样子:

Listlist;if(param1 != null){

PageHelper.startPage(1, 10);

list=countryMapper.selectIf(param1);

}else{

list= new ArrayList();

}

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

Listlist;if(param1 != null){

PageHelper.startPage(1, 10);try{

list=countryMapper.selectAll();

}finally{

PageHelper.clearPage();

}

}else{

list= new ArrayList();

}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐