MVC框架实现数据库数据分页查询(版本二)
之前的版本一是JDBC与EL实现数据库数据在前端页面查询,此篇用MVC模式实现了分页查询,简单的MVC入门例子,博客有很多全面且详细的解释,我摘要其中的几段,首先有一张简图可以了解MVC框架的执行原理:
MVC模式(三层架构模式)
(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
MVC模式最早由Trygve Reenskaug在1974年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件设计模式。MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观。软件系统通过对自身基本部份分离的同时也赋予了各个基本部分应有的功能。专业人员可以通过自身的专长分组:
(控制器Controller)- 负责转发请求,对请求进行处理。
(视图View) - 界面设计人员进行图形界面设计。
(模型Model) - 程序员编写程序应有的功能(实现算法等等)、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
MVC工作原理
MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。
视图
视图是用户看到并与之交互的界面。对老式的Web应用程序来说,视图就是由HTML元素组成的界面,在新式的Web应用程序中,HTML依旧在视图中扮演着重要的角色,但一些新的技术已层出不穷,它们包括Macromedia Flash和像XHTML,XML/XSL,WML等一些标识语言和Web services. 如何处理应用程序的界面变得越来越有挑战性。MVC一个大的好处是它能为你的应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。
模型
模型表示企业数据和业务规则。在MVC的三个部件中,模型拥有最多的处理任务。例如它可能用像EJBs和ColdFusion Components这样的构件对象来处理数据库。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
控制器
控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后确定用哪个视图来显示模型处理返回的数据。 现在我们总结MVC的处理过程,首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。
介绍完了,接下来就分页查询的步骤:
还是老规矩直接上代码:
第一部分(导包,配置文件,JSP前端部分):
[jar包下载地址]http://archive.apache.org/dist
配置文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/factory
jdbc.username=root
jdbc.password=ps123456
JSP部分:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
table tr td{
border:1px solid black;
}
</style>
</head>
<body>
<form action="${pageContext.request.contextPath}/listEmp">
雇员姓名:<input name="ename"/><input type='submit' value="查询"/>
</form>
<table style="width:80%">
<tr>
<td>雇员编号</td>
<td>雇员姓名</td>
<td>雇员薪水</td>
<td>雇员职位</td>
</tr>
<c:forEach var="tt" items="${requestScope.pb.data}">
<tr>
<td>${tt.empno}</td>
<td>${tt.ename}</td>
<td>${tt.sal}</td>
<td>${tt.job }</td>
</tr>
</c:forEach>
</table>
<a href="listEmp?curPage=${requestScope.pb.prePage}">上一页</a>
<c:forEach var="i" begin="1" end="${requestScope.pb.totalPage}" step="1">
<a href="listEmp?curPage=${i}">${i}</a>
</c:forEach>
当前页:${requestScope.pb.curPage} 总页数是:${requestScope.pb.totalPage} 总条数是:${requestScope.pb.total} <a href="listEmp?curPage=${requestScope.pb.nextPage}">下一页</a>
</body>
</html>
第二属性类部分(Emp):
package cn.pk.entity;
public class Emp {
private String empno;
private String ename;
private String deptno;
private int sal;
private String job;
public String getEmpno() {
return empno;
}
public void setEmpno(String empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getDeptno() {
return deptno;
}
public void setDeptno(String deptno) {
this.deptno = deptno;
}
public int getSal() {
return sal;
}
public void setSal(int sal) {
this.sal = sal;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
第三controller部分(EmpServlet):
package cn.pk.controller;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.lang.StringUtils;
import cn.pk.entity.Emp;
import cn.pk.servlet.EmpService;
import cn.pk.servlet.impl.EmpServiceImpl;
import cn.pk.util.MyDbUtils;
import cn.pk.util.PageBean;
/**
* Servlet implementation class EmpSerlvet
*/
@WebServlet(urlPatterns="/listEmp")
public class EmpSerlvet extends HttpServlet {
private EmpService service=new EmpServiceImpl();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String ename = request.getParameter("ename");
String curPage=request.getParameter("curPage");
String pageNum= request.getParameter("pageNum");
try {
PageBean<Emp> pb=service.queryEmp(ename, curPage, pageNum);
request.setAttribute("pb", pb);
request.getRequestDispatcher("/emp.jsp").forward(request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第四工具类Util部分:
连接数据库:
/**
*
*/
package cn.pk.util;
import java.io.IOException;
import java.util.Properties;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
/**
* @author 摸摸大白兔
*时间 2017年10月19日 下午3:55:46
*
*/
public class MyDbUtils {
public static BasicDataSource bds=new BasicDataSource();
static {
Properties p=new Properties();
try {
p.load(MyDbUtils.class.getResourceAsStream("/jdbc.properties"));
bds.setDriverClassName(p.getProperty("jdbc.driver"));
bds.setUrl(p.getProperty("jdbc.url"));
bds.setUsername(p.getProperty("jdbc.username"));
bds.setPassword(p.getProperty("jdbc.password"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
分页帮助类:
package cn.pk.util;
import java.util.List;
/**
* 分页的帮助类
* @author 摸摸大白兔
*时间 2017年10月20日 下午2:14:26
*
*/
public class PageBean<T> {
public void calc() {
}
/**
* 构造方法
* @param curPage当前页
* @param pageNum每页显示的条数
* @param total总条数
*/
public PageBean(int curPage,int pageNum,int total) {
//计算上一页
this.prePage = curPage==1?1:curPage-1;
//计算总页数
this.totalPage=total%pageNum==0?total/pageNum:total/pageNum+1;
//下一页
this.nextPage=curPage==totalPage?totalPage:curPage+1;
//当前页数的下标
this.startIndex=(curPage-1)*pageNum;
this.total=total;
this.curPage=curPage;
this.pageNum=pageNum;
}
/**
* 当前查询的默认当前页=1;
* (页面传递参数)
*/
private int curPage;
/**
* 每一页的数据条数默认10条
* 页面传递的参数
*/
private int pageNum=10;
/**
* 上一页
*根据当前页判断
*curPage=1 prePage=1;
*curPage>1 prePage=curPage-1;
*/
private int prePage;
/**
* 下一页
* curPage=totalpage nextPage=totalpage;
* curPage<totalpage nextPage=curPage+1;
*/
private int nextPage;
/**
* 总共多少页数(若总条数除以每页条数有余数则页数+1)
* 总条数total/每一页条数pageNum
* total%pageNum==0?total/pageNum:total/pageNum+1;
*/
private int totalPage;
/**
* 总共多少条
* 数据库查询
*/
private int total;
private List<T> data;
/**
* 开始的索引
* startIndex = (curPage-1)*pageNum
*/
private int startIndex;
public int getCurPage() {
return curPage;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public void setCurPage(int curPage) {
this.curPage = curPage;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public int getPrePage() {
return prePage;
}
public void setPrePage(int prePage) {
this.prePage = prePage;
}
public int getNextPage() {
return nextPage;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
第五模型层的持久层部分:
package cn.pk.dao.impl;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.lang.StringUtils;
import cn.pk.dao.EmpDao;
import cn.pk.entity.Emp;
import cn.pk.util.MyDbUtils;
/**
* 模型层的持久层(数据库的sql语句)
* @author 摸摸大白兔
*时间 2017年10月20日 下午1:24:12
*
*/
public class EmpDaoImp implements EmpDao{
public int countEmp(String ename) throws SQLException {
QueryRunner qr=new QueryRunner(MyDbUtils.bds);
String sql="select count(*) as myCount from newemp";
if(StringUtils.isNotEmpty(ename)) {
sql+=" where ename like '%"+ename+"%'";
}
Map map=(Map)qr.query(sql,new MapHandler());
return Integer.parseInt(map.get("myCount").toString());
}
@Override
public List<Emp> queryEmp(String ename,int startIndex,int pageNum) throws SQLException {
QueryRunner qr=new QueryRunner(MyDbUtils.bds);
String sql="select * from newemp";
if(StringUtils.isNotEmpty(ename)) {
sql+=" where ename like '%"+ename+"%'";
}
sql+=" limit "+startIndex+","+pageNum;
List<Emp> empList = (List<Emp>)qr.query(sql,new BeanListHandler(Emp.class));
return empList;
}
}
借口类部分:
package cn.pk.dao;
import java.sql.SQLException;
import java.util.List;
import cn.pk.entity.Emp;
public interface EmpDao {
public int countEmp(String ename) throws SQLException ;
List<Emp> queryEmp(String name,int startIndex,int pageNum) throws SQLException;
}
第六servlet部分:
package cn.pk.servlet.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import cn.pk.dao.EmpDao;
import cn.pk.dao.impl.EmpDaoImp;
import cn.pk.entity.Emp;
import cn.pk.servlet.EmpService;
import cn.pk.util.PageBean;
public class EmpServiceImpl implements EmpService{
private EmpDao dao=new EmpDaoImp();
@Override
public PageBean<Emp> queryEmp(String ename,String curPage,String pageNum) throws Exception {
//如果第一次没有访问当前页
if(StringUtils.isEmpty(curPage)) {
curPage="1";
}
if(StringUtils.isEmpty(pageNum)) {
pageNum="10";
}
//转换为int类型
int curPageIn =Integer.parseInt(curPage);
int pageNumIn= Integer.parseInt(pageNum);
int total=dao.countEmp(ename);
PageBean<Emp> pb=new PageBean<>(curPageIn,pageNumIn,total);
List<Emp> queryEmp = dao.queryEmp(ename,pb.getStartIndex(), pb.getPageNum());
pb.setData(queryEmp);
return pb;
}
}
servlet接口类部分:
package cn.pk.servlet;
import java.sql.SQLException;
import java.util.List;
import cn.pk.entity.Emp;
import cn.pk.util.PageBean;
public interface EmpService {
public PageBean<Emp> queryEmp(String ename, String curPage,String pageNum) throws Exception;
}
最后的执行效果如图:
好了。一个简易完整版的数据库表查询就完成了;