分析:效果是进行页面展示,因此可对页面的组成元素进行分析,一般包括数据总数,每页总数,待显示页数,当前页数据内容,如下图:
因此按照上述分析我们可以从两条线出发解决这个问题:
1)查询要显示的内容;
2)通过查询符合条件的总数量(因为每页显示的条数是设定的,因此查询到总数量就可以计算出页数)。
从SQL角度而言就是查询符合条件的总的数量(select conut() …),至于每页的数据就可以通过设定查询限制查询对应的数据(利用limit,比如第三页内容那就可以通过页数3和每页要显示的条数最为限定条件进行第三页要显示数据的查询),主要分页查询不是一次查询出所有数据,而是我们翻到那一页就查询那一页,这样体验较好不至于数据较多时查询较慢。
实践:下面按照从下向上开发思路分别阐述对应的dao->service->controller各层的内容功能和内容。
1.建立对应的Pager工具类,进行数据总量、每页数据量、页数等参数的配置,如下代码所示:
public class Pager {
private int curPage;// 待显示页
private int perPageRows;// 每页显示的记录数
private int rowCount;// 记录总数
private int pageCount;// 总页数
public int getCurPage() {
return curPage;
}
public void setCurPage(int curPage) {
this.curPage = curPage;
}
public int getPerPageRows() {
return perPageRows;
}
public void setPerPageRows(int perPageRows) {
this.perPageRows = perPageRows;
}
public int getRowCount() {
return rowCount;
}
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
}
//计算页数
public int getPageCount() {
return (rowCount + perPageRows -1)/perPageRows;
}
//分页显示时,获取当前页的第一条记录的索引
public int getFirstLimitParam() {
return (this.curPage -1) * this.perPageRows;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
}
其中最核心的是计算当前页的第一条记录索引因为这样才能确定查询条件查询出数据库中对应的内容填充到当前页。
2.持久化层dao,按照分析建立两部分SQL语句,即总数据量和当前页内容:
1)查询总数
public String count(Map<String, Object> params) {
return new SQL() {
{
SELECT("count()");
FROM(“product_info”);
if (params.get(“productInfo”) != null) {
ProductInfo productInfo = (ProductInfo) params.get(“productInfo”);
if (productInfo.getCode() != null && !productInfo.getCode().equals("")) {
WHERE(“code = #{productInfo.getCode}”);
}
if (productInfo.getName() != null && !productInfo.getName().equals("")) {
WHERE(“name LIKE CONCAT (’%’, #{productInfo.getName},’%’)”);
}
if (productInfo.getBrand() != null && !productInfo.getBrand().equals("")) {
WHERE(“brand LIKE CONCAT (’%’, #{productInfo.getBrand},’%’)”);
}
if (productInfo.getType() != null && productInfo.getType().getId() > 0) {
WHERE(“tid = #{productInfo.type.id}”);
}
if (productInfo.getPriceFrom() > 0) {
WHERE(“price > #{productInfo.priceFrom}”);
}
if (productInfo.getPriceTo() > 0) {
WHERE(“price <= #{productInfo.priceTo}”);
}
}
}
}.toString();
}
2)当前页内容
public String selectWithParam(Map<String, Object> params) {
String sql = new SQL() {
{
SELECT("*");
FROM(“product_info”);
if (params.get(“productInfo”) != null) {
ProductInfo productInfo = (ProductInfo) params.get(“productInfo”);
if (productInfo.getCode() != null && !productInfo.getCode().equals("")) {
WHERE(“code = #{productInfo.getCode}”);
}
if (productInfo.getName() != null && !productInfo.getName().equals("")) {
WHERE(“name LIKE CONCAT (’%’, #{productInfo.getName},’%’)”);
}
if (productInfo.getBrand() != null && !productInfo.getBrand().equals("")) {
WHERE(“brand LIKE CONCAT (’%’, #{productInfo.getBrand},’%’)”);
}
if (productInfo.getType() != null && productInfo.getType().getId() > 0) {
WHERE(“tid = #{productInfo.type.id}”);
}
if (productInfo.getPriceFrom() > 0) {
WHERE(“price > #{productInfo.priceFrom}”);
}
if (productInfo.getPriceTo() > 0) {
WHERE(“price <= #{productInfo.priceTo}”);
}
}
}
}.toString();
if (params.get(“pager”) != null) {
// 定义从那页开始,共几条数据
sql += " limit #{pager.firstLimitParam}, #{pager.perPageRows}";
}
return sql;
}
本部分是利用注解的方式编写对应的SQL映射语句。
3业务逻辑层service,还是如上从两个方面编写:
1)查询总数的业务逻辑
public Integer count(Map<String, Object> params) {
// TODO Auto-generated method stub
return productInfoDao.count(params);
}
2)查询当前页内容
public List findProductInfo(ProductInfo productInfo, Pager pager) {
Map<String, Object> params = new HashMap<>();
params.put(“productInfo”, productInfo);
int recordCount = productInfoDao.count(params);
pager.setRowCount(recordCount);
if (recordCount > 0) {
params.put(“pager”, pager);
}
return productInfoDao.selectByPage(params);
}
3.控制器层controller,接收视图层传递的参数并返回内容,参数包括页面设定的每页数据量,数据内容,返回的内容包括数据总数和每页数据内容:
@RequestMapping(value = “/list”)
@ResponseBody
public Map<String, Object> list(Integer page, Integer rows, ProductInfo productInfo) {
Pager pager = new Pager();
pager.setCurPage(page);
pager.setPerPageRows(rows);
//创建map对象
Map<String, Object> params = new HashMap<>();
params.put(“productInfo”, productInfo);
//获取满足条件的商品总数
int totalCount = productInfoService.count(params);
//获取满足条件的当前页商品列表
List productInfos = productInfoService.findProductInfo(productInfo, pager);
Map<String, Object> result = new HashMap<String, Object>();
result.put(“total”, totalCount);
result.put(“rows”, productInfos);
return result;
}
综上所述,分页查询主要从两个角度数据量总数和当前页内容两个角度进行分页查询,上述阐述主要也是逻辑关系进行说明,因此每页提出完整的代码,只是根据需求贴出了核心代码辅助分页查询逻辑的说明。
分页查询探究
最新推荐文章于 2024-10-20 13:15:00 发布