核心提示:以前用jsp和原生的JDBC实现过分页,现在一看,不仅代码冗余,而且可读性差,今天分享一种简洁的实现方式,我用起来是很方便的。一.概述主要思想就是建一个Page类,所有跟分页有关的参数都放在这个类里,...
以前用jsp和原生的JDBC实现过分页,现在一看,不仅代码冗余,而且可读性差,今天分享一种简洁的实现方式,我用起来是很方便的。
一.概述
主要思想就是建一个Page类,所有跟分页有关的参数都放在这个类里,这个类里放一个集合用来装返回的数据,前端用JSTL提供的标签进行展示。这里需要注意的是,Oracle与mysql不同,没有提供类似limit这样的函数,稍微麻烦一点,我们用rownum做分页。
我们举个例子,在数据库(Oracle)里有名为Game的一张表,字段有no,name,company,type,现在要做的是在前端用jsp展示,看代码
二.结构
1. model包中有两个类: AnyPage和Game类
public class AnyPage{ private int currentPage; //画面接收到的当前页数。 private int dataCountOnePage = 5; //每页要显示的数据量。 private int indexRowNum; //当前页要显示的第一条记录的行号。 private int lastRowNum; //当前页要显示的最后一条记录的行号。 private int dataCount; //数据库记录总数 private int pageCount; //页码数 private List games; //每页要显示的数据集合。 private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } public List getGames() { return games; } public void setGames(List games) { this.games = games; } public int getDataCount() { return dataCount; } //根据数据库总数据量算出总页数 public void setDataCount(int dataCount) { this.dataCount = dataCount; pageCount = dataCount / dataCountOnePage; if (dataCount % dataCountOnePage != 0) { pageCount = pageCount + 1; } } public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount; } public int getCurrentPage() { return currentPage; } //根据当前的页数算出开始和结束的rownum public void setCurrentPage(int currentPage) { this.currentPage = currentPage; this.lastRowNum = currentPage * dataCountOnePage; this.indexRowNum = this.lastRowNum - (dataCountOnePage - 1); } public int getDataCountOnePage() { return dataCountOnePage; } public void setDataCountOnePage(int dataCountOnePage) { this.dataCountOnePage = dataCountOnePage; } public int getIndexRowNum() { return indexRowNum; } public void setIndexRowNum(int indexRowNum) { this.indexRowNum = indexRowNum; } public int getLastRowNum() { return lastRowNum; } public void setLastRowNum(int lastRowNum) { this.lastRowNum = lastRowNum; } } //Game类 public class Game { //对应数据库的字段 private int no; private String name; private String company; private String type; public int getNo() { return no; } public void setNo(int no) { this.no = no; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
在这里AnyPage采用泛型,也是一个小技巧。
2.mapper包:GameMapper的接口和XML配置文件
//mapper接口
public interface GameMapper {
//分页查询
List<Game> selectByPage(AnyPage anyPage);
//统计总数量
AnyPage selectDataCount();
}
//XML配置
<mapper namespace="com.easy.mapper.GameMapper">
<select id="selectByPage" parameterType="com.easy.model.AnyPage" resultType="com.easy.model.Game">
select no, name, company, type
from
(select rownum r, no, name, company, type
from game where no > #{no})
where r between #{indexRowNum} and #{lastRowNum}
</select>
<select id="selectDataCount" resultType="com.easy.model.AnyPage">
select count(no) dataCount from game
</select>
</mapper>
3.service包:GameService接口
//定义分页查询的接口
public interface GameService {
public AnyPage selectByPage(AnyPage anyPage);
}
**4.serviceImpl包**
//具体实现类,这里用的是spring整合
@Service
public class GameServiceImpl implements GameService{
@Autowired
GameMapper gameMapper;
@Override
public AnyPage selectByPage(AnyPage anyPage) {
//根据参数查询到分页后的game
List list = gameMapper.selectByPage(anyPage);
//查询总数量
AnyPage anyPage2 = gameMapper.selectDataCount();
anyPage2.setGames(list);
//以AnyPage的形式返回
return anyPage2;
}
}
5.Controller包
```
//这里使用的是SpringMVC作为控制器
public class GameController {
@Autowired
GameService gameService;
@RequestMapping("sp")
public String selectByPage(AnyPage anyPage, Map map) {
//在服务层将分页代码处理好
AnyPage anyPage2 = gameService.selectByPage(anyPage);
anyPage2.setCurrentPage(anyPage.getCurrentPage());
///以map作为数据模型
map.put("anyPage", anyPage2);
return "games";
}
}
6.前端:jsp
<h1>分页展示</h1>
<table border="1" cellspacing="0">
<tr>
<td>#</td>
<td>游戏名</td>
<td>公司</td>
<td>类型</td>
</tr>
<c:forEach items="${requestScope.anyPage.games}" var="game" varStatus="b1">
<tr>
<td>${b1.count}</td>
<td>${game.name }</td>
<td>${game.company }</td>
<td>${game.type }</td>
</tr>
</c:forEach>
</table>
<c:forEach begin="1" end="${requestScope.anyPage.pageCount }" var="page">
<c:if test="${not page eq requestScope.anyPage.currentPage }">
<a href="${pageContext.request.contextPath }/gc/sp?currentPage=${page}">
${page}
</a>
</c:if>
<c:if test="${not page eq requestScope.anyPage.currentPage }">
${page}
</c:if>
</c:forEach>
这里面我截取了其中重要的部分,JSTL提供的标签真的很方便,省去了大量的java代码,可读性性也比较高,还有需要注意的是,最后ye页面编码角标的判断,循环判断的方式也是很好的想法。怎么样,很简单吧。


