1、关于逻辑分类和物理分页
分页可分为逻辑分页和物理分页
- 逻辑分页是一次性把全部数据查询加载进内存 ,然后再进行分页。这样优点是减少IO次数,适合频繁访问、数据量少的情况。缺点是不适合大数据量,容易造成内存溢出。
- 物理分页是利用limit语法在数据库中进行分页。他的优点是适合分页大数据量数据。缺点是频繁查询数据库,消耗性能。
2、Mybatis实现分页功能
mybatis实现分页有三种方式
- 直接使用SQL语句,利用limit关键字分页(物理分页)
- RowBounds(逻辑分页)
- 第三方插件PageHelper(物理分页)
环境:spring boot+mybatis
2.1 SQL语句实现分页
limit语法 limit [offset,] rows
offset 偏移量,从第条数据分页,默认为0
rows 行数,要拿多少数据
在mapper接口中
@Select("select count(*) from role")
int allRoleCount();
@Select("select * from role limit #{offset},#{rows}")
List<Role> pageRole(int offset,int rows);
@Autowired
private RoleMapper roleMapper;
//sql分页
@Test
public void test2(){
int pageNum = 3; //查第几页
int pageSize = 3; //每页几条数据
int count = roleMapper.allRoleCount(); //总条数
//计算出:共有多少页、这页的偏移量offset是多少
int pagesNum = (count / pageSize) + 1; //共有多少页
int offset = (pageNum - 1) * pageSize; //偏移量
List<Role> roles = roleMapper.pageRole(offset,pagesNum);
System.out.println(roles);
//最后把分页数据封装到Page类中返回,这里不做演示
}
这种方式缺点是比较麻烦,要自己计算分页数据和封装Page类。优点是自定义性强。
2.2 RowBounds实现分页
在mapper接口中
@Select("select count(*) from role")
int allRoleCount();
@Select("select * from role")
List<Role> pageRowBoundsRole(RowBounds rowBounds);
//RowBounds分页
@Test
public void test3(){
int pageNum = 1; //查第几页
int pageSize = 3; //每页几条数据
int count = roleMapper.allRoleCount(); //总条数
//计算出:共有多少页、这页的偏移量offset是多少
int pagesNum = (count / pageSize) + 1; //共有多少页
int offset = (pageNum - 1) * pageSize; //偏移量
RowBounds rowBounds = new RowBounds(offset,pageSize);
List<Role> roles = roleMapper.pageRowBoundsRole(rowBounds);
System.out.println(roles);
//最后把分页数据封装到Page类中返回,这里不做演示
}
2.3 第三方插件PageHelper
导入第三方依赖包
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
//PageHelper
@Test
public void test1(){
PageHelper.startPage(1, 3);
List<Role> roles = roleMapper.allRole();
System.out.println(roles);
PageInfo<Role> pageInfo = new PageInfo<>(roles);
System.out.println(pageInfo.getNextPage()); //下一页
System.out.println(pageInfo.getPrePage()); //上一页
System.out.println(pageInfo.getPageNum()); //当前页
System.out.println(pageInfo.getPageSize()); //每页多少条
System.out.println(pageInfo.getSize()); //当前页的条数
System.out.println(pageInfo.getTotal()); //总条数
System.out.println(pageInfo.getPages()); //总页数
}
这种方式最喜欢了😍😘😘😘,不用计算,也不用自己封装。
仅一行代码就可以做到分页功能了,真的太神奇了!
他的原理大概是:在PageHelper.startPage()方法中把分页数据存储到ThreadLocal中,然后利用PageInterceptor拦截roleMapper.allRole()SQL执行方法,然后从ThreadLocal中取出分页参数进行SQL语句limit拼接。
3、MybatisPlus实现分页功能
- 内置分页查询mybatis-plus(物理分页)
- PageHelper(物理分页)
环境:spring boot+mybatis plus
3.1 内置分页查询
在BaseMapper中定义了两种内置分页查询方法
两个的区别:
selectPage返回对象数组
selectMapsPage返回Map数组
先配置添加分页拦截器PaginationInnerInterceptor
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//定义mp拦截器
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//添加分页的拦截器
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
return mybatisPlusInterceptor;
}
}
//内置分页查询
@Test
public void selectByPage(){
IPage page = new Page(1,2);
roleDao.selectPage(page, null);
System.out.println("当前页:"+page.getCurrent());
System.out.println("每页显示数:"+page.getSize());
System.out.println("总条数:"+page.getTotal());
System.out.println("总页数:"+page.getPages());
System.out.println("数据:"+page.getRecords()); //[Role(id=4, roleName=项目经理, dec=null, deleted=0, version=2), Role(id=5, roleName=测试工程师2, dec=null, deleted=0, version=1)]
}
//内置分页查询
@Test
public void selectMapsByPage(){
IPage page = new Page(1,2);
roleDao.selectMapsPage(page, null);
System.out.println("当前页:"+page.getCurrent());
System.out.println("每页显示数:"+page.getSize());
System.out.println("总条数:"+page.getTotal());
System.out.println("总页数:"+page.getPages());
System.out.println("数据:"+page.getRecords());//[{role_name=项目经理, deleted=0, id=4, version=2}, {role_name=测试工程师2, deleted=0, id=5, version=1}]
}
3.2 第三方PageHelper分页助手
和mybatis使用差不多。