java分页的方式可以有很多种,如:
1.limit分页
service代码中传offset,limit参数到sql查询
select * from student where province = #{province} limit #{offset},#{limit}
2.手动截取list分页
计算出分页所需的开始和结束条目
List<StudentEnroll> pageList = studentEnrolls.subList(fromIndex, toIndex);
3.pageHelper分页
PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件,使用该插件,省去了繁琐的逻辑代码处理;
1.pom引入
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
2.config配置
pagehelper配置在mybatis配置中,使用interceptor拦截查询
@Configuration
@EnableTransactionManagement
public class MybatisConfig implements TransactionManagementConfigurer {
@Resource
private DataSource dataSource;
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("com.young.bean");
//分页插件,设置mybatis的拦截器
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
//3.3.0版本可用 - 分页参数合理化,默认false禁用
// 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
// 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageHelper.setProperties(properties);
//添加分页插件
bean.setPlugins(new Interceptor[]{pageHelper});
//添加XML目录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
bean.setMapperLocations(resolver.getResources("classpath:mapping/*.xml"));
return bean.getObject();
}
@Bean
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
3.实现
public PaginationResult<MemberQueryResult> query(MemberQueryParam param) {
Page<MemberQueryResult> page = SqlUtil.getPage(param);
//memberMapper.selectAll();
memberMapper.selectByConditidon(param);
PaginationResult<MemberQueryResult> paginationResult = new PaginationResult();
paginationResult.setTotal(page.getTotal());
paginationResult.setData(page.getResult());
return paginationResult;
}
public class SqlUtil {
public static <T extends PaginationParam, O extends Serializable> Page<O> getPage(T param) {
Page<O> page;
if (null == param || null == param.getPagination()) {
page = PageHelper.startPage(0, 0, true, false, true);
} else {
Pagination pagination = param.getPagination();
page = PageHelper.startPage(pagination.getStartPos(), pagination.getPageSize(), true, false, true);
}
return page;
}
}
@Data
public class MemberQueryParam extends PaginationParam implements Serializable {
private String id;
private String memberId;
private String name;
private String phone;
private String reserve1;
private String reserve2;
}
@Data
public class PaginationParam implements Serializable {
private Pagination pagination;
}
@Data
public class Pagination implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 每页显示的行数
*/
private int pageSize = 10;
/**
* 开始页数
*/
private int startPos = 1;
}
4.简单分析原理
(1)pagehelper先通过PageHelper.startPage(...)方法将分页参数计入ThreadLocal线程,缓存起来;
(2)待持久层sql执行时,PageHelper继承Interceptor接口中的intercept()方法,拦截查询;
(3)doProcessPage()执行分页逻辑:获取(1)中缓存的参数,通过Parser(根据你的数据库类型,如:MysqlParser,OracleParser等)getPageSql()方法重新拼接sql语句,执行分页查询;若传入的count参数是true,则会创建count查询的MappedStatement对象,查询总条数(省去了开发自己编写sql);此处的查询结果都会存放在(1)中缓存的page对象中,供service直接使用。