文章目录
一、需求分析
以这个案例为例,要完成以下需求:
-
点击上方导航栏,查询对应类别的旅游路线信息。
-
下方显示分页栏,内容包括:首页、上一页、下一页、末页等。
-
点击任意一页,该页的内容随之对应改变。
-
显示总页数与总记录数。
-
要求分页栏索引为10个。
1、【数据表分析】
涉及到的表结构:tab_category和tab_route,通过cid相关联。
2、【MySQL分页查询语句】
select * from 表名 limit 开始索引 , 每页的条数;
还有一个很容易推得得式子:开始索引 = (当前页码 -1)* 每页显示的行数。
3、【分页数据分析】
在这个过程中,牵扯到哪些必要的数据,以及这些数据如何得到。
-
客户端发送的请求数据
-
当前的页数:
currentPage
,因为到时候一定是要根据当前的页码来查询,来翻页,甚至给按钮加上样式。 -
根据这里的需求,还需要传递对应
cid
,后端接收之后根据cid查找对应的route。
-
-
开发者规定的数据
- 每页规定的记录数:
pageSize
。
- 每页规定的记录数:
-
数据库查询到的数据
- 总记录数:
totalCount
,总记录数可以根据需要展示页面,最重要的是,可以通过总记录数和每页记录数计算出总页码。 - 每页显示的数据,到时候返回根据cid查询到的数据。
- 总记录数:
-
计算得到的数据
- 总页数:totalPage,根据totalCount和pageSize算得。
二、后端代码实现
1、【PageBean对象封装】
/**
* @author Summerday
*
* 分页pagebean对象
*/
public class PageBean<T>{
//总记录数
private Integer totalCount;
//总页数
private Integer totalPage;
//当前页码
private Integer currentPage;
//每页显示的条数
private Integer pageSize;
//每页显示的数据集合
private List<T> list;
//省略getter和setter方法
}
2、【Servlet层】
/**
* @author Summerday
*/
@WebServlet("/route/*")
public class RouteServlet extends BaseServlet {
private RouteService service= new RouteServiceImpl();
public void pageQuery(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收参数
String currentPageStr = request.getParameter("currentPage");
String cidStr = request.getParameter("cid");
//tomcat7需要对get请求参数进行处理
rname = new String(rname.getBytes("iso8859-1"),"utf-8");
int cid = 0;
String nullStr = "null";
//处理参数
if(cidStr!=null&&cidStr.length()>0&& !nullStr.equals(cidStr)){
cid = Integer.parseInt(cidStr);
}
int currentPage = 1;
//处理参数
if(currentPageStr!=null&¤tPageStr.length()>0){
currentPage = Integer.parseInt(currentPageStr);
}
//处理参数(黑马视频中是获取客户端的数据,我个人感觉不是很合理,于是直接在服务器赋值10)
int pageSize = 10;
//调用service查询pagebean对象
PageBean<Route> pb = service.pageQuery(cid, currentPage, pageSize);
//将pagebean对象序列化为json返回
writeValue(pb,response);
}
}
3、【Service层】
/**
* @author Summerday
*/
public class RouteServiceImpl implements RouteService {
private RouteDao routeDao = new RouteDaoImpl();
@Override
public PageBean<Route> pageQuery(int cid, int currentPage, int pageSize) {
//封装pagebean
PageBean<Route> pb = new PageBean<>();
//设置当前页码
pb.setCurrentPage(currentPage);
//设置每页显示条数
pb.setPageSize(pageSize);
//设置总记录数
int totalCount = routeDao.findTotalCount(cid);
pb.setTotalCount(totalCount);
//设置当前页显示的数据集合
//开始的记录数
int start = (currentPage - 1) * pageSize;
List<Route> list = routeDao.findByPage(cid, start, pageSize);
pb.setList(list);
//(刚好除尽的情况)设置总页数 = 总记录数/每页显示条数
int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
pb.setTotalPage(totalPage);
//返回PageBean对象
return pb;
}
}
4、【Dao层】
/**
* @author Summerday
*/
public class RouteDaoImpl implements RouteDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 计算总记录数
* @param cid cid
* @return 总记录数
*/
@Override
public int findTotalCount(int cid) {
String sql = "select count(*) from tab_route where cid = ?";
//返回一个值,用forObject
return template.queryForObject(sql,Integer.class,cid);
}
/**
* 查询每页的数据信息
* @param cid cid
* @param start 开始索引
* @param pageSize 每页的记录数
* @return 每页的数据信息
*/
@Override
public List<Route> findByPage(int cid, int start, int pageSize) {
String sql = "select * from tab_route where cid = ? limit ? , ?";
return template.query(sql,new BeanPropertyRowMapper<>(Route.class),cid,start,pageSize);
}
}
三、前台代码实现
该案例前台视图层使用的是html页面,因此无法从域中获取数据,遂用过发送异步ajax请求实现前后端数据交互。
1、【封装获取请求参数的方法】
//根据传递过来的参数name获取对应的值
function getParameter(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i");
var r = location.search.substr(1).match(reg);
if (r!=null) return (r[2]); return null;
}
设定导航栏中的链接为:var li = '<li><a href="route_list.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';
就可以通过getParameter方法将cid获取,实现cid的传递。
2、【异步ajax请求】
接下来也就是比较关键的部分,发送异步ajax请求,以下几种情况都需要发送请求:
- 页面加载完成后发送。
- 点击页码按钮时发送。
于是就想到将他抽取为一个方法。
function load(cid, currentPage) {
//发送ajax请求,请求route/pageQuery,传递cid
$.get("route/pageQuery", {cid: cid, currentPage: currentPage}, function (pb) {
//分页工具条的数据展示
//展示总页码+总记录数(黑马提供的数据库只有cid=5的数据)
$("#totalPage").html(pb.totalPage);
$("#totalCount").html(pb.totalCount);
var lis = "";
var firstPage = '<li οnclick="javascript:load('+cid+',1)" style="cursor: pointer"><a href="javascript:void(0)">首页</a></li>';
//上一页的序号,如果为第一页,就设置为第一页
var beforeNum = pb.currentPage - 1;
if (beforeNum <= 0) {
beforeNum = 1;
}
var prevPage = '<li οnclick="javascript:load(' + cid + ',' + beforeNum + ')" style="cursor: pointer" class="threeword"><a href="#">上一页</a></li>';
lis += firstPage;
lis += prevPage;
//展示分页页码
/*
一共展示10个页码,能够达到前五后四的效果
如果前面不够5个后面补齐10个
如果后面不足4个,前面补齐10ge
*/
//定义开始位置begin.结束位置end
var begin;
var end;
if(pb.totalPage<10){
//总页码<10
begin = 1;
end = pb.totalPage;
}else{
//总页码>=10
begin = pb.currentPage-5;
end = pb.currentPage+4;
//前面不够5个,后面补齐10个
if(begin<1){
begin = 1;
end = begin+9;
}
//后面不足4个,前面补齐10个
if(end>pb.totalPage){
end = pb.totalPage;
begin = end-9;
}
}
for (var i = begin; i <= end; i++) {
var li;
//为当前页码加上样式
if (pb.currentPage == i) {
li = '<li class="curPage" style="cursor: pointer" οnclick="javascript:load(' + cid + ',' + i + ')"><a href="javascript:void(0)">' + i + '</a></li>';
} else {
//创建页码的li
li = '<li style="cursor: pointer" οnclick="javascript:load(' + cid + ',' + i + ')"><a href="javascript:void(0)">' + i + '</a></li>';
}
//拼接字符串
lis += li;
}
var nextNum = currentPage + 1;
if (nextNum > pb.totalPage) {
nextNum = pb.totalPage;
}
var nextPage = '<li οnclick="javascript:load(' + cid + ','+nextNum+')" style="cursor: pointer" class="threeword"><a href="javascript:void(0);">下一页</a></li>';
var lastPage = '<li οnclick="javascript:load(' + cid + ','+pb.totalPage+')" style="cursor: pointer" class="threeword"><a href="javascript:void(0);">末页</a></li>';
lis += nextPage;
lis += lastPage;
//将list内容设置到ul中
$("#pageNum").html(lis);
//列表数据展示
var route_lis = "";
for (var i = 0; i < pb.list.length; i++) {
//获取{rid:1,rname:"xxx"}
var route = pb.list[i];
var li = "省略具体信息。。。,例如route.rimage、route.rname等"
route_lis += li;
}
$("#route").html(route_lis);
//定位到页面顶部
window.scrollTo(0,0);
})
}