2019/9/10 周二
学习内容:使用MVVC分层开发理念实现页面上的分页功能
需要实现信息的分页功能,可以借助数据库提供的limit的关键字,limit a,b 可以设置从第a条开始(下标从0开始),显示b条信息。
基于MVC分层开发的思想,分页功能的实现也可以从底层模型层开始写。
在MVC分层中,各层所映射的都是数据库中的数据表,如Model层就是几张数据表就创建几个类。但实现分页功能时,最好的办法是把前端页面所要展示的内容也看成一个对象,定义一个类专门返回分页所需的信息。
public class PageModel { //代表泛型,使用该类时定义泛型的类型。泛型增加了PageModel类的通用性
// 将当前是第几页、每页展示条数、一个多少条信息、该页所要展示出来的信息集合设置为属性
private List list; // 结果集,用来存储查询结果
private int count; // 总共多少条
private int pageSize; // 每页多少条
private int pageNo; // 第几页
/** 提供获取总页数 */
public int getTotalPags() {
return (count+pageSize-1)/pageSize;
}
/** 获取首页 */
public int getTopPageNo() {
return 1;
}
/** 获取尾页 */
public int getBottomPageNo() {
return getTotalPags();
}
/** 获取上一页 */
public int getPreviousPageNo() {
if(pageNo<=1) {
return 1;
}else {
return pageNo-1;
}
}
/** 获取下一页 */
public int getNextPageNo() {
if(pageNo>=getTotalPags()) {
return getTotalPags();
} else {
return pageNo+1;
}
}
/** get和set方法略 */
}
在我们的案例中,原来需要展示的是商品信息,所以这里就在商品的DAO层添加基于展示页面的sql查询方法。
在上面的四个属性中,第几页和每页展示多少条是由前端页面传过来的,而总的信息条数和需要展示的信息的集合就需要从数据库中查出来,因此DAO层中要提供获取这两者的方法。(接口就不放上来了,直接是DAO实现层)
/**获取商品总数*/
public int getCommodityCount() {
int count = 0;
try {
Connection conn = DBHelper.getConnection();
String sql = "select count(*) from commodity";
ResultSet rs = DBHelper.executeQuery(conn, sql, null);
rs.next();
count = rs.getInt(1);
DBHelper.closeConnection(conn);
} catch (Exception e) {
e.printStackTrace();
}
return count;
}
/**获取该页要显示的商品的集合*/
public List getCommodityListWithPage(int pageNo,int pageSize) {
ArrayList list = new ArrayList<>();
try {
Connection conn = DBHelper.getConnection();
String sql = "select * from commodity limit ?,?";
ArrayList param = new ArrayList();
param.add((pageNo-1)*pageSize);
param.add(pageSize);
ResultSet rs = DBHelper.executeQuery(conn, sql, param);
while(rs.next()) {
String c_id = rs.getString(1);
String c_name = rs.getString(2);
String c_madein = rs.getString(3);
String c_type = rs.getString(4);
int c_inprice = rs.getInt(5);
int c_outprice = rs.getInt(6);
int c_num = rs.getInt(7);
Commoditytype ct = new CommoditytypeDaoImpl().getCommodityTypeById(c_type);
Commodity c = new Commodity(c_id,c_name,c_madein,c_type,ct,c_inprice,c_outprice,c_num);
list.add(c);
}
DBHelper.closeConnection(conn);
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
再往上应该是Controller层,但Controller层主要负责业务逻辑处理,而对于分页来说,更多算是一个功能,每一次翻页都需要用到,就像数据库连接工具类DBHelper也是每次连接数据库都要用到的,因此把它作为一个util包下的工具类会更恰当。
这个类主要用来实例化一个PageModel对象,每一次翻页操作,都会有一个新的PageModel对象。
public class PageHelper {
public static PageModel findCommodity(int pageNo,int pageSize) {
PageModel pageModel = new PageModel<>();
pageModel.setCount(new CommodityDaoImpl().getCommodityCount());
List list = new CommodityDaoImpl().getCommodityListWithPage(pageNo, pageSize);
pageModel.setList(list);
pageModel.setPageNo(pageNo);
pageModel.setPageSize(pageSize);
return pageModel;
}
}
定义一个分页跳转的Servlet,除了常规操作外,还需要从前端页面获取当前页码和每页展示的条数,并通过刚刚创建的PageHelper工具类来实例化一个PageModel的对象,加入session中:
int pageNo = new Integer(req.getParameter("pageNo"));
int pageSize = new Integer(req.getParameter("pageSize"));
PageModel page = PageHelper.findCommodity(pageNo, pageSize);
HttpSession session = req.getSession();
session.setAttribute("pageView", page);
记得把Servlet添加到web.xml文件中
另外,因为登录和注册之后会跳转到展示页面,此时应该展示第一页的信息,默认显示5条。需要在登录和注册的Servlet中,去掉原来获取所有商品信息集合的内容,加上通过实例化 PageModel对象来获取某一页的视图,也就是每一页需要展示的商品信息。
PageModel page = PageHelper.findCommodity(1, 5);
session.setAttribute("pageView", page);
在页面中,原来需要的是所有商品的集合,现在就是通过PageModel的实例对象,来获取了当前页码所要展示商品的集合了
PageModel p = (PageModel) session.getAttribute("pageView");
int pageNo = p.getPageNo();
int pageSize = p.getPageSize();
List cList = p.getList();
(如果之前没有在登录和注册的Servlet中,实例化 PageModel并添加到session,这里的p就会出现空指针异常,一定不能漏了这一步。)
接下来,在页面中显示翻页工具栏,点击页码可以显示对应页的商品信息,如果当前在第一页,那么“首页”、“第一页”、“1”都是没有链接的,否则才链接到Servlet去实现页面跳转,使用字符串拼接把当前页码和每页多少条作为参数传递;其他页同理。
if (pageNo == 1) {
out.print("首页 ");
} else {
out.print("首页 ");
}
if (pageNo == 1) {
out.print("上一页 ");
} else {
out.print("上一页 ");
}
for (int i = 1; i <= p.getTotalPags(); i++) {
if (pageNo == i) {
out.print(i + " ");
continue;
}
out.print(
"" + i + " ");
}
if (pageNo == p.getBottomPageNo()) {
out.print("下一页 ");
} else {
out.print("下一页 ");
}
if (pageNo == p.getBottomPageNo()) {
out.print("尾页 ");
} else {
out.print("尾页 ");
}
%>
下拉框可以让用户选择每页显示多少条信息,当选择内容有改变时触发onChange方法,同样要用Servlet来刷新页面内容
每页展示 条