创建BookDao并定义实现书本查全部方法,最后完成Junit方法测试。
public class BookDao extends BaseDao{ /** * 添加 * @param book */ public void addBook(Book book){ Connection con = null; PreparedStatement ps = null; try{ //获取连接对象 con=DBHelper.getConnection(); ps=con.prepareStatement("insert into t_book values(?,?,?,?)"); ps.setString(1,book.getBookid()); ps.setString(2,book.getBookname()); ps.setFloat(3,book.getPrice()); ps.setString(4,book.getBooktype()); //执行SQL语句并返回影响行数 int i=ps.executeUpdate(); if(i<0) throw new Exception("执行失败,影响函数为0"); }catch (Exception e){ e.printStackTrace(); }finally { DBHelper.close(con,ps,null); } } /** * 模糊查询 * @param book * @return */ public List getByLike(Book book, PageBean pageBean) { String sql = "select * from t_book where 1=1"; if (StringUtils.isNotBlank(book.getBookname())) sql += " and bookname like '%" + book.getBookname() + "%'"; System.out.println(sql); return super.executeQuery(sql, pageBean, new CallBack() { @Override public List foreachRs(ResultSet rs) throws SQLException { return CommonUtils.toList(rs,Book.class); } }); } }
创建BookServlet并调用BookDao中查全部方法实现书本查询。
public class BookServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取前端页面传入的查询条件 String bookname = req.getParameter("bookname"); //创建Book对象 Book book=new Book(); book.setBookname(bookname); //调用模糊查询方法 PageBean pageBean=new PageBean(); BookDao bookDao=new BookDao(); //获取前端传入的请求参数集 pageBean.setRequest(req); List books = bookDao.getByLike(book,pageBean); //将查询结果保存到request作用域中 req.setAttribute("books",books); //将pageBean保存到request作用域中 req.setAttribute("pageBean",pageBean); //转发 req.getRequestDispatcher("index.jsp").forward(req,resp); } }
1)打开web.xml,配置中文乱码过滤器EncodingFilter和书本查询Servlet控制器;
encodingFilter com.zking.pagintation.uitl.EncodingFilter encodingFilter /* Servlet com.zking.pagintation.servlet.BookServlet Servlet /Servlet.do /index.jsp
2)创建BookServlet.jsp页面实现书本查询效果展示。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="z" uri="/zking" %> 通用分页 通用分页
书本编号 书本名称 书本价格 书本类型 ${b.bookid} ${b.bookname} ${b.price} ${b.booktype}
limit语法
select * from table_name limit [offset,] rows
参数说明
参数 | 说明 |
---|---|
offset | 指定第一个返回记录行的偏移量(即从哪一行开始返回),注意:初始行的偏移量为0 |
rows | 返回具体行数 |
创建PageBean分页标记类,用于定义分页相关要素。
/** * 分页工具类 */ public class PageBean { //当前页码 private int page=1; //每页条数 private int rows=10; //总机录数 private int total=0; //是否分页标记 private boolean pagination=true; //增强属性 //返回上一条请求的url路径 private String url; //获取上一次请求的所有请求参数集合 private Map maps; public void setRequest(HttpServletRequest req){ //1、获取前端传入的分页三要素(page,rows,pagination) String page = req.getParameter("page"); String rows = req.getParameter("rows"); String pagination = req.getParameter("pagination"); this.setPage(page); this.setRows(rows); this.setPagination(pagination); //2、获取上一次请求的URL路径 //req.getContextPath == 获取项目名 //req.getServletPath() == 获取servlet请求路径名 //req.getRequestURL == req.getContextPath+req.getServletPath() this.url=req.getRequestURI(); //3、获取上一次请求的所有请求参数集合 this.maps = req.getParameterMap(); } /** * 返回limit分页查询的开始位置 * @return */ public int getStartIndex(){ return (this.page-1)*this.rows; } //重载set方法 public void setPage(String page) { if(null!=page) this.page = Integer.parseInt(page); } public void setRows(String rows) { if(null!=rows) this.rows = Integer.parseInt(rows); } public void setPagination(String pagination) { if(null!=pagination) this.pagination = Boolean.parseBoolean(pagination); } /** * //分页方法 * //计算总分页 * @return 总分页数 */ public int getMaxPager(){ int max = this.total/this.rows; //除不尽有余数 if(this.total%this.rows!=0) max++; return max; } /** * 上一页方法 * @return 上一页页数 */ public int getPrevPager(){ int prev = this.page-1; if(prev<=1) prev=1; return prev; } /** * 下一页方法 * @return 下一页页数 */ public int getNextPager(){ int next=this.page+1; if(next>=getMaxPager()) next=getMaxPager(); return next; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Map getMaps() { return maps; } public void setMaps(Map maps) { this.maps = maps; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public boolean isPagination() { return pagination; } public void setPagination(boolean pagination) { this.pagination = pagination; } @Override public String toString() { return "PageBean{" + "page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + ", url='" + url + '\'' + ", maps=" + maps + '}'; } }
创建BaseDao通用分页类并定义相关分页方法。
public class BaseDao { /** * 通用分页方法 (分页或不分页) * @param sql 普通SQL语句 * @param pageBean 分页标记对象 * @return 返回分页结果集 */ public List executeQuery(String sql, PageBean pageBean,CallBack callBack){ Connection con=null; PreparedStatement ps=null; ResultSet rs=null; try{ con= DBHelper.getConnection(); if(null!=pageBean&&pageBean.isPagination()){ //分页 //1)根据满足的条件查询分页总记录数 String countSQL = this.getCountSQL(sql); ps=con.prepareStatement(countSQL); rs=ps.executeQuery(); if(rs.next()){ int total = rs.getInt(1); //将查询得到的总记录数存入Page Bean对象中的total属性 pageBean.setTotal(total); } //2)根据满足的条件查询分页结果集 sql = this.getPagerSQL(sql, pageBean); } ps=con.prepareStatement(sql); rs=ps.executeQuery(); return callBack.foreachRs(rs); }catch (Exception e){ e.printStackTrace(); }finally { DBHelper.close(con,ps,rs); } return null; } }
在executeQuery方法中根据PageBean对象及对象属性pagination识别是否分页。
分页:查询分页结果、集查询总记录数
将普通的SQL语句转换成分页查询的SQL语句
/** * 将普通的SQL语句转换成分页查询的SQL语句 * @param sql 普通SQL语句 * @param pageBean 分页标记对象 * @return 分页查询的SQL语句 */ private String getPagerSQL(String sql,PageBean pageBean){ return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows(); }
/** * 将普通sql语句转换成查总记录数的sql * @param sql * @return 查询总记录数的SQL语句 */ private String getCountSQL(String sql){ return "select count(*) from ("+sql+") temp"; }
不分页:只查询数据结果集(不查询分页记录和总记录数)
在BaseDao类中定义匿名内部接口,该接口中的forEach方法只用于循环遍历ResultSet查询结果集并返回List
/** * 用于遍历结果集数据的回调接口 * @author Administrator * @param */ public static interface CallBack{ public List foreachRs(ResultSet rs) throws SQLException; }
修改executeQuery方法,将匿名内部接口CallBack当做入参传入方法中。
public List executeQuery(String sql, PageBean pageBean,CallBack callBack){ Connection con=null; PreparedStatement ps=null; ResultSet rs=null; try{ con= DBHelper.getConnection(); if(null!=pageBean&&pageBean.isPagination()){ //分页 //1)根据满足的条件查询分页总记录数 String countSQL = this.getCountSQL(sql); ps=con.prepareStatement(countSQL); rs=ps.executeQuery(); if(rs.next()){ int total = rs.getInt(1); //将查询得到的总记录数存入Page Bean对象中的total属性 pageBean.setTotal(total); } //2)根据满足的条件查询分页结果集 sql = this.getPagerSQL(sql, pageBean); } ps=con.prepareStatement(sql); rs=ps.executeQuery(); return callBack.foreachRs(rs); }catch (Exception e){ e.printStackTrace(); }finally { DBHelper.close(con,ps,rs); } return null; }
Junit是一个Java测试框架,使编写可靠和高效的测试变得容易。它可以用于大多数语言制作的应用程序,但特别适合于测试Java应用程序。Junit也可以用来创建自动测试。
Junit框架是最流行的Java测试框架之一。它提供了一些功能,使编写测试变得容易,包括支持多个测试用例、断言和报告。Junit也是多功能的,允许用各种语言编写测试。
setUp():在方法之前执行
tearDown:在方法之后执行
public class BookDaoTest { @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testQueryBookPager() { fail("Not yet implemented"); } }
Junit中的setUp和tearDown方法是根据方法数量来决定的
package com.zking.pagintation.uitl; import javax.servlet.http.HttpServletRequest; import java.util.Map; /** * 分页工具类 */ public class PageBean { //当前页码 private int page=1; //每页条数 private int rows=10; //总机录数 private int total=0; //是否分页标记 private boolean pagination=true; //增强属性 //返回上一条请求的url路径 private String url; //获取上一次请求的所有请求参数集合 private Map maps; public void setRequest(HttpServletRequest req){ //1、获取前端传入的分页三要素(page,rows,pagination) String page = req.getParameter("page"); String rows = req.getParameter("rows"); String pagination = req.getParameter("pagination"); this.setPage(page); this.setRows(rows); this.setPagination(pagination); //2、获取上一次请求的URL路径 //req.getContextPath == 获取项目名 //req.getServletPath() == 获取servlet请求路径名 //req.getRequestURL == req.getContextPath+req.getServletPath() this.url=req.getRequestURI(); //3、获取上一次请求的所有请求参数集合 this.maps = req.getParameterMap(); } /** * 返回limit分页查询的开始位置 * @return */ public int getStartIndex(){ return (this.page-1)*this.rows; } //重载set方法 public void setPage(String page) { if(null!=page) this.page = Integer.parseInt(page); } public void setRows(String rows) { if(null!=rows) this.rows = Integer.parseInt(rows); } public void setPagination(String pagination) { if(null!=pagination) this.pagination = Boolean.parseBoolean(pagination); } /** * //分页方法 * //计算总分页 * @return 总分页数 */ public int getMaxPager(){ int max = this.total/this.rows; //除不尽有余数 if(this.total%this.rows!=0) max++; return max; } /** * 上一页方法 * @return 上一页页数 */ public int getPrevPager(){ int prev = this.page-1; if(prev<=1) prev=1; return prev; } /** * 下一页方法 * @return 下一页页数 */ public int getNextPager(){ int next=this.page+1; if(next>=getMaxPager()) next=getMaxPager(); return next; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Map getMaps() { return maps; } public void setMaps(Map maps) { this.maps = maps; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public boolean isPagination() { return pagination; } public void setPagination(boolean pagination) { this.pagination = pagination; } @Override public String toString() { return "PageBean{" + "page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + ", url='" + url + '\'' + ", maps=" + maps + '}'; } }
package com.zking.pagintation.tag; import com.zking.pagintation.uitl.PageBean; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyTagSupport; import java.util.Map; import java.util.Set; public class PaginationTag extends BodyTagSupport { private PageBean pageBean; public PageBean getPageBean() { return pageBean; } public void setPageBean(PageBean pageBean) { this.pageBean = pageBean; } @Override public int doStartTag() throws JspException { try{ JspWriter out = pageContext.getOut(); out.print(toHtml()); }catch (Exception e){ e.printStackTrace(); } return SKIP_BODY; } private String toHtml(){ //判断PageBean是否为空 if(null!=pageBean&&pageBean.isPagination()){ //定义StringBuffer可变字符串 //面试题:String/StringBuffer/StringBuilder/的区别 StringBuffer sb=new StringBuffer(); //拼接div跟标签 sb.append(""); //拼接form标签对象 sb.append(""); //拼接分页信息 sb.append("第"+pageBean.getPage()+"页/总"+pageBean.getMaxPager()+"页数"); //拼接首页、上一页、下一页、末页 if(pageBean.getPage()==1) sb.append("首页 上一页"); else { sb.append("首页"); sb.append("上一页"); } if(pageBean.getPage()==pageBean.getMaxPager()) sb.append("下一页 末页"); else { sb.append("下一页"); sb.append("末页"); } //拼接javascpit sb.append(""); sb.append(""); return sb.toString(); } return ""; } @Override public int doEndTag() throws JspException { return EVAL_PAGE; } }
详见课件"z.tld"文件