JavaWeb之分页的实现——基于Mysql(通用)
相信大家也在网站上看到的分页效果的吧!那么现在来一起看看他的思路以及代码还有效果图吧
基于MySql数据库的通用分页 通用分页核心思路:将上一次查询请求再发一次,只不过页码变了 实现步骤: 1)先查询全部数据 Junit测试 baseDao<T>、CallBack<K> 2)通用分页实现 pagebean
1. PageBean 分页三要素 page 页码 视图层传递过来 rows 页大小 视图层传递过来 total 总记录数 后台查出来 pagination 是否分页 视图层传递过来 getStartIndex() 基于MySql数据库分页,获取分页开始标记 ------------------------- url 请求路径 视图层传递过来 map 参数集合 视图层传递过来 setRequest(HttpServletRequest req) 设置请求参数 getMaxPager() 获取最大页码 getProviousPager() 获取上一页 getNextPager() 获取下一页
2. 后台 2.1 entity 2.2 dao BaseDao<T> 1)匿名内部接口 2)分页查询方法,接口方法传参 (返回:总记录数+指定页码并满足条件的记录集) 3)二次查询的条件要一致 getCountSql()/getPagerSql() 2.3 控制层 Servlet req.getContextPath();//获取根目录 req.getServletPath();//获取请求路径
3. junit(代码测试的一种方法) java单元测试/白盒测试 setUp tearDown 测试用例
package com.zking.pagination.dao;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.zking.pagination.entity.Book;
import com.zking.pagination.util.PageBean;
import com.zking.pagination.util.PinYinUtil;
class BookDaoTest {
//Servlet生命周期:init/service/destory
Book book=null;
BookDao bookDao=new BookDao();
@BeforeEach
void setUp() throws Exception {
book=new Book();
}
@AfterEach
void tearDown() throws Exception {
}
@Test
void testAddBook() {
for(int i=0;i<81; i++) {
book=new Book();
book.setBook_name("西游记第"+(i+1)+"章");
book.setBook_name_pinyin(PinYinUtil.toPinyin("西游记第"+(i+1)+"章").toLowerCase());
book.setBook_price(99f);
book.setBook_type("神话");
bookDao.addBook(book);
}
}
@Test
void testQueryBookPager() {
book.setBook_name("2");
PageBean pageBean=new PageBean();
pageBean.setPage(2);
List<Book> books=bookDao.queryBookPager(book,pageBean);
System.out.println("总记录数:"+pageBean.getTotal());
books.forEach(System.out::println);
}
}
Servlet中的init和destory方法只会运行一次 Junit中的setUp和tearDown方法是根据方法数量来决定的
首先我是跟着我自己eclipse中的文件来发代码的!
所需要的jar包如下:
话不多说上通用分页的代码啦!
package com.zking.pagination.action;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zking.pagination.dao.BookDao;
import com.zking.pagination.entity.Book;
import com.zking.pagination.util.PageBean;
public class BookAction 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");
//实例化BookDao
BookDao bookDao=new BookDao();
//实例化book
Book book=new Book();
book.setBook_name(bookname);
//创建PageBean
PageBean pageBean=new PageBean();
pageBean.setRequest(req);
//实现书本查询
List<Book> books=bookDao.queryBookPager(book,pageBean);
//将查询结果books保存request作用域中
req.setAttribute("books", books);
req.setAttribute("pageBean", pageBean);
//转发到指定页面并显示查询结果
req.getRequestDispatcher("/bookList.jsp").forward(req, resp);
}
}
//通过分页方法(既支持分页,也可以不支持分页)通用方法
package com.zking.pagination.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import com.sun.glass.ui.MenuItem.Callback;
import com.zking.pagination.util.DBHelper;
import com.zking.pagination.util.PageBean;
public class BaseDao<T> {
public static interface CallBack<K>{
//只用于遍历ResultSet结果集
public List<K> foreachRs(ResultSet rs) throws SQLException;
}
/**
* 通过分页方法(既支持分页,也可以不支持分页)
* @param sql 普通的SQl
* @param pageBean 分页对象
* @return 查询结果集
*/
public List<T> executQuery(String sql,
PageBean pageBean,CallBack<T> callBack){
Connection conn=null;
PreparedStatement stmt=null;
ResultSet rs=null;
try {
conn=DBHelper.getConnection();
//判断PageBean分页对象判断是否分页
if(null!=pageBean&&pageBean.isPagination()) {
//1)根据满足条件查询总记录数
String countSQL = this.getCountSQL(sql);
//创建执行对象
stmt=conn.prepareStatement(countSQL);
//执行SQL语句并返回总记录数
rs=stmt.executeQuery();
//获取总记录数
if(rs.next()) {
pageBean.setTotal(rs.getInt(1));;
}
//2)根据满足条件查询分页结果集
sql= this.getPagerSQL(sql, pageBean);
}
//创建执行对象
stmt=conn.prepareStatement(sql);
rs=stmt.executeQuery();
return callBack.foreachRs(rs);
} catch (Exception e) {
e.printStackTrace();
}finally {
DBHelper.close(conn, stmt, rs);
}
return null;
}
/**
* 将普通的SQl语句转换成总记录数的SQL语句
* select * from t_book
* select * from t_book...
* select book_id,book_name from t_book
* select book_id,book_name from t_book where...
* ----->
* select count(0) from t_book where...
*
* @param sql 普通的SQl
* @return 查询总记录的SQl
*/
private String getCountSQL(String sql) {
return "select count(0) from ("+sql+") temp";
}
/**
* * 将普通的SQl语句转换成总记录数的SQL语句
* select * from t_book
* select * from t_book...
* select book_id,book_name from t_book
* select book_id,book_name from t_book where...
* ----->
* 将普通的SQL语句转换成查询分页结果集的SQL语句
* @param sql 普通的SQL
* @param pageBean 分页对象(包含当前页码和每页条数,用于计算分页的关键数据)
* @return
*/
private String getPagerSQL(String sql,PageBean pageBean) {
return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();
}
}
//连接Mysql的代码:
package com.zking.pagination.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* 提供了一组获得或关闭数据库对象的方法
*
*/
public class DBHelper {
private static String driver;
private static String url;
private static String user;
private static String password;
static {// 静态块执行一次,加载 驱动一次
try {
InputStream is = DBHelper.class
.getResourceAsStream("config.properties");
Properties properties = new Properties();
properties.load(is);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("pwd");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获得数据连接对象
*
* @return
*/
public static Connection getConnection() {
try {
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void close(ResultSet rs) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Statement stmt) {
if (null != stmt) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn) {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn, Statement stmt, ResultSet rs) {
close(rs);
close(stmt);
close(conn);
}
public static boolean isOracle() {
return "oracle.jdbc.driver.OracleDriver".equals(driver);
}
public static boolean isSQLServer() {
return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
}
public static boolean isMysql() {
return "com.mysql.jdbc.Driver".equals(driver);
}
public static void main(String[] args) {
Connection conn = DBHelper.getConnection();
DBHelper.close(conn);
System.out.println("isOracle:" + isOracle());
System.out.println("isSQLServer:" + isSQLServer());
System.out.println("isMysql:" + isMysql());
System.out.println("数据库连接(关闭)成功");
}
}
//书本分页查询(方法代码):
/**
* 2.书本分页查询 query/find/select/get
* @param book
* @return
*/
@SuppressWarnings("unchecked")
public List<Book> queryBookPager(Book book,PageBean pageBean){
String sql="select book_id,book_name,book_name_pinyin,book_price,"
+ "book_type from t_book where 1=1";
//拼接查询条件,按照书本名称模糊查询
if(StringUtils.isNotBlank(book.getBook_name()))
sql+=" and book_name like '%"+book.getBook_name()+"%'";
//按照书本编号降序排序
sql+=" order by book_id desc";
System.out.println(sql);
Collections.sort(new ArrayList<>(),new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
return 0;
}
});
return super.executQuery(sql, pageBean, new CallBack<Book>() {
@Override
public List<Book> foreachRs(ResultSet rs) throws SQLException {
List<Book> lst=new ArrayList<>();
//定义Book对象
Book b=null;
//循环遍历结果集
while(rs.next()) {
//创建Book对象
b=new Book();
b.setBook_id(rs.getInt("book_id"));
b.setBook_name(rs.getString("book_name"));
b.setBook_name_pinyin(rs.getString("book_name_pinyin"));
b.setBook_price(rs.getFloat("book_price"));
b.setBook_type(rs.getString("book_type"));
lst.add(b);
}
return lst;
}
});
4. 视图层 PageTag
package com.zking.pagination.tag;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.zking.pagination.util.PageBean;
public class PaginationTag extends BodyTagSupport {
private PageBean pageBean;
@Override
public int doEndTag() throws JspException {
return EVAL_PAGE;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.write(toHtml());
} catch (Exception e) {
e.printStackTrace();
}
return SKIP_BODY;
}
private String toHtml() {
//判断是否分页
if(null==pageBean||!pageBean.isPagination())
return "";
else {
StringBuilder sb=new StringBuilder();
//TODO
sb.append("<div style=\"float:right\">");
//拼接Form表单
sb.append("<form id=\"pageBeanForm\" action=\""+pageBean.getUrl()+"\" method=\"post\">");
//设置page隐藏域
sb.append("<input type=\"hidden\" name=\"page\"/>");
//拼接请求参数集合
Map<String, String[]> map = pageBean.getParams();
//获取请求参数集合键值对
Set<Entry<String,String[]>> entrySet = map.entrySet();
//遍历请求参数键值对
for (Entry<String, String[]> entry : entrySet) {
//获取请求参数名,也就是来自于表单中的name属性名称
String name=entry.getKey();
//如果参数为page,则continue跳过
if(name.equals("page"))
continue;
//获取请求参数对应的值,String[]
String[] values=entry.getValue();
//遍历value值
for (String value : values) {
//拼接请求参数
sb.append("<input type='hidden' name='"+name+"' value='"+value+"'/>");
}
}
sb.append("</form>");
//拼接共几页/第几页
sb.append("共"+pageBean.getMaxPager()+"页/第"+pageBean.getPage()+"页,");
//拼接首页、上一页、下一页、末页
if(pageBean.getPage()==1)
sb.append("首页 上一页 ");
else {
sb.append("<a href=\"javascript:gotoPage(1)\">首页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getProviousPager()+")\">上一页</a> ");
}
if(pageBean.getPage()==pageBean.getMaxPager())
sb.append("下一页 末页 ");
else {
sb.append("<a href=\"javascript:gotoPage("+pageBean.getNextPager()+")\">下一页</a> ");
sb.append("<a href=\"javascript:gotoPage("+pageBean.getMaxPager()+")\">末页</a> ");
}
//拼接跳转页码
sb.append("<input type=\"text\" id=\"p\" style=\"width:20px;\"/>");
sb.append("<input type=\"button\" value=\"GO\" onclick=\"javascript:skipPage();\"/>");
//拼接javascript跳转方法
sb.append("<script type=\"text/javascript\">\r\n" +
"function gotoPage(page){\r\n" +
" document.getElementById(\"pageBeanForm\").page.value=page;\r\n" +
" document.getElementById(\"pageBeanForm\").submit();\r\n" +
"}");
sb.append("function skipPage(){\r\n" +
" var page=document.getElementById(\"p\").value;\r\n" +
" if(isNaN(page)||page<1||page>="+pageBean.getMaxPager()+"){\r\n" +
" alert('请输入1~"+pageBean.getMaxPager()+"之间数字!');\r\n" +
" return false;\r\n" +
" }\r\n" +
" gotoPage(page);\r\n" +
"}\r\n" +
"</script>");
sb.append("</div>");
return sb.toString();
}
}
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
}
点击分页按钮,将上一次的请求在发(请求)一次
效果图如下:
注1:不能将分页表单嵌套到其它表单中,否则不能提交表单!!! 不能将分页表单嵌套到其它表单中,否则不能提交表单!!! 不能将分页表单嵌套到其它表单中,否则不能提交表单!!!
今天就分享到这里啦! 代码就是提供一个思路小伙伴们可以参考一下!
相关文章
- MySQL 如何实现大表的高效迁移(mysql大表迁移)
- MySQL联合查询实现两个表数据的结合(mysql两个表联合查询)
- MySQL数据库添加外键:一种实现数据关联的方式(mysql数据库添加外键)
- MySQL 同步表:实现对两张表的完美同步(mysql同步两张表)
- MySQL连接之C语言实现(c如何与mysql连接)
- MySQL数据库实现文件上传功能(mysql上传文件)
- 利用MySQL创建安全账号实现安全管理(mysql创建账号)
- MySQL的If条件查询:实现复杂查询(mysqlif条件查询)
- MySQL实现获取系统时间的姿势(mysql获取系统时间)
- 通过MySQL二级考试的秘诀(mysql二级考试)
- 数据PHP实现MySQL数据导出的实现方法(php导出mysql)
- MySQL实现主主复制和主从复制的方法及优缺点分析(mysql主主从)
- 优化提升MySQL位运算性能的优化策略(mysql位运算性能)
- MySQL字段索引实现数组功能(mysql字段数组)
- MySQL 统计表:轻松实现数据分析(mysql 统计表)
- 轻松实现连接虚拟机MySQL,提高工作效率(连接虚拟机的mysql)
- 如何正确安装MySQL数据库(怎么安装mysql数据库)
- MySQL中正则表达式截取字符串简易教程(mysql正则截取字符串)
- MySQL企业版:提高工作效率的必备工具(mysql企业版下载)
- MySQL中如何实现一对多关系(mysql中一对多)
- 深入浅出MySQL中Key目录详解(mysql中key是目录)
- 查MySQL数据库CRUD功能实现(c mysql 增删改)
- C与MySQL结合实现处理图片的功能(c# mysql 图片)
- 使用Bat登录MySQL快速实现数据库管理(bat登陆mysql)
- 使用CMD快速建立MySQL数据库(cmd建mysql数据库)
- MySQL如何实现循环判断(mysql中判断循环)
- MySQL Join的用法及实现方法(mysql。join)
- MySQL数据表实现不存在则更新操作(mysql 不存在则更新)
- Mysql数据同步无法实现原因分析(mysql不能同步)