今天学习了一个新的,嗯,也不能算是新的知识,就是如何在项目中实现分页的功能,主要来说从前端选择页数(如首页、上一页、下一页、尾页),然后系统根据参数去数据库查找指定数量与位置的记录,返回给界面并展示出来。
由于篇幅所限,也是为了凸显出重点,本文只展示部分的核心代码。
注:项目环境为SpringBoot,使用JdbcTemplate来进行数据库操作。环境与分页功能的实现并无多大影响。嗯,重在思想。
页面效果如下:
1.前提:分页辅助类的实现
首先,为了实现分页功能,我们需要一个能够将前端请求参数与后端SQL查询参数进行转换的东西,更直接地来说,我们需要一个分页辅助类,命名为PageDto,关键内容如下:
public class PageDto implements Serializable{
private static final long serialVersionUID = 6289664328222015781L;
private int total_rows;//总记录数 从数据库查询
private int current_page;//当前页 前端传递过来的
private int page_size;//每页条数 应该有,自定义(可写在项目配置文件中)
private int total_pages;//总页数 可以算
private int offset_row;//偏移量 可以算
private boolean hasPrev;//是否有前一页
private boolean hasNext;//是否有下一页
public PageDto(int total_rows, int current_page, int page_size) {
super();
this.total_rows=total_rows;
this.current_page=current_page;
this.page_size=page_size;
this.offset_row = ( this.current_page - 1 ) * this.page_size ;
this.total_pages=this.total_rows%this.page_size ==0
? this.total_rows/this.page_size : this.total_rows/this.page_size +1;
this.hasPrev=this.current_page==1 ? false:true;
this.hasNext=this.total_pages==this.current_page ? false:true;
}
}
有关各种get和set方法这里就不展现了。
2.前端参数接收与转换
有了PageDto辅助类,我们就可以根据前端传递过来的参数去new一个PageDto对象,然后再根据用这个对象去查询数据库表信息。如下为某个Controller类的一个请求处理方法:
// /test/emp/list/1 ------分页
@RequestMapping("/list/{current_page}")
public String list(@PathVariable(name="current_page") int current_page, Model model) {
System.out.println(">>>>list>>>>....");
int total_rows = empService.total_rows();//empService为容器自动注入的bean,total_rows()这个方法是在dao层定义的方法,查询表的总记录数
PageDto pageDto = new PageDto(total_rows,current_page,page_size);
System.out.println(pageDto.toString());
List<Emp> emps = empService.listEmpByPage(pageDto);//根据new的PageDto对象去进行SQL查询
model.addAttribute("emps",emps);//将查询结果返回给界面
model.addAttribute("pageDto",pageDto);
return "emp/list";
}
3.SQL:
到了这里,我们手里已经有了PageDto的实例对象,在这个对象里面保存了offset_row(偏移量,也就是下一个应该被查询的记录位置m)和page_size(每次要查询的记录数n)。这个时候SQL语句的写法也就很明朗了——使用select....limit m,n语句进行查询即可。
下面是我的Dao的一个查询方法:
@Override
public List<Emp> listEmpByPage(PageDto pageDto) {
// TODO Auto-generated method stub
List<Emp> emps = jdbcTemplate.query("select emp_id,emp_name,emp_age,emp_birthday,emp_salary,emp_ctime"
+ " from t_emp order by emp_ctime desc limit ?,?",
new Object[] {pageDto.getOffset_row(),pageDto.getPage_size()},
new int[] {Types.INTEGER,Types.INTEGER},
new RowMapper<Emp>() {
@Override
public Emp mapRow(ResultSet rs, int rowNum) throws SQLException {
// TODO Auto-generated method stub
return new Emp(rs.getLong("emp_id"),rs.getString("emp_name"),
rs.getInt("emp_age"),rs.getDate("emp_birthday"),
rs.getDouble("emp_salary"),rs.getTimestamp("emp_ctime"));
}
});
return emps;
}
如代码所示,要求查询的那一页的记录被查询出来了。
4.总结
最后来概括一下,实现分页功能的关键点就在于如何去给出limit m,n中m这个偏移量与n这个页记录数。在这里给出的是通过一个辅助类PageDto来更好地实现这一点的,否则的话计算起来就很麻烦了。