前言:給大家講解全堆疊通用分頁查詢
碼字不易,點個關注
轉載請說明!
開發工具:eclipse
思維導圖:

目錄
一. 所需要的jar包
二.后端
1.資料庫幫助類
2.BaseDao——通用查詢分頁父類
3.BookDao—書籍dao層類
4.PageBean—分頁工具類
三.前端
1.tld檔案
2.pageTag助手類
3.前端界面 index.jsp
四.Servlet
一. 所需要的jar包

二.后端
1.資料庫幫助類
DBAccess—資料庫助手類
package com.hpw.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 DBAccess {
private static String driver;
private static String url;
private static String user;
private static String password;
static {// 靜態塊執行一次,加載 驅動一次
try {
InputStream is = DBAccess.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.cj.jdbc.Driver".equals(driver);
}
public static void main(String[] args) {
Connection conn = DBAccess.getConnection();
System.out.println(conn);
DBAccess.close(conn);
System.out.println("isOracle:" + isOracle());
System.out.println("isSQLServer:" + isSQLServer());
System.out.println("isMysql:" + isMysql());
System.out.println("資料庫連接(關閉)成功");
}
}
這里是對我們定義的XML檔案進行決議來決定資料源,相比于之前定義的DBHelper類適用范圍更廣,
對應的dtl檔案
#oracle9i
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:ora9
#user=test
#pwd=test
#sql2005
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#url=jdbc:sqlserver://localhost:1423;DatabaseName=test
#user=sa
#pwd=sa
#sql2000
#driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB
#user=sa
#pwd=888888
#mysql8
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=true
user=root
pwd=123456
#mysql5
#driver=com.mysql.jdbc.Driver
#url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=true
#user=root
#pwd=pppppp
EncodingFiter—編碼過濾類
package com.hpw.util;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 中文亂碼處理
*
*/
public class EncodingFiter implements Filter {
private String encoding = "UTF-8";// 默認字符集
public EncodingFiter() {
super();
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 中文處理必須放到 chain.doFilter(request, response)方法前面
res.setContentType("text/html;charset=" + this.encoding);
if (req.getMethod().equalsIgnoreCase("post")) {
req.setCharacterEncoding(this.encoding);
} else {
Map map = req.getParameterMap();// 保存所有引數名=引數值(陣列)的Map集合
Set set = map.keySet();// 取出所有引數名
Iterator it = set.iterator();
while (it.hasNext()) {
String name = (String) it.next();
String[] values = (String[]) map.get(name);// 取出引數值[注:引數值為一個陣列]
for (int i = 0; i < values.length; i++) {
values[i] = new String(values[i].getBytes("ISO-8859-1"),
this.encoding);
}
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String s = filterConfig.getInitParameter("encoding");// 讀取web.xml檔案中配置的字符集
if (null != s && !s.trim().equals("")) {
this.encoding = s.trim();
}
}
}
2.BaseDao——通用查詢分頁父類
package dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.hpw.util.DBAccess;
import com.hpw.util.PageBean;
import com.hpw.util.StringUtils;
import entity.Book;
public class BaseDao<T> {
/**
* 所有Dao層的父類 提供解決方案 1.抽取變化部分作為引數 sql ,Class物件 結果集 2.抽取公共的父類,把重復性的代碼剝離出來
*
* @param <T>
*/
public List<T> keylist(String sql, Class<T> clz) throws Exception {
// 不能確定集合裝什么東西
// 子類Dao繼承BaseDao<T>子類傳遞什么類.class,那么集合中放到就是什么
List<T> list = new ArrayList<T>();
Connection con = DBAccess.getConnection();
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
/**
* 代碼不一樣 具體體現在 不同的表有不同欄位 那么物體類對應的屬性就會不一樣
*
* 1.實體化了一個物件 2.從ResultSet的物件的屬性獲取值(bid)獲取值賦值給了前面的實體化物件 3.把已經賦值了的物件 ,添加到集合中
*/
T t = clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
list.add(t);
}
return list;
}
/**
* 通用的分頁查詢
*
* @param sql
* @param clz
* @return
* @throws Exception
*/
public List<T> executeQuery(String sql, Class<T> clz ,PageBean pageBean) throws Exception {
List<T> list = new ArrayList<T>();
Connection con = DBAccess.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
/*
* 是否需要分頁?
* 無需分頁 (專案中的下拉框,查詢條件教員下拉框 無需分頁)
* 必須分頁(專案中串列類需求,訂單串列,商品串列,學生串列)
*/
if(pageBean != null && pageBean.isPagination()) {
String countSQL = getcountSQL(sql);
ps = con.prepareStatement(countSQL);
rs = ps.executeQuery();
if(rs.next()) {
pageBean.setTotal(String.valueOf(rs.getObject(1)));
}
//挪動到下面,是因為最后才處理回傳的結果集
//必須分頁(串列需求)
// *-- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
// -- pagesql=sql limit (page-1)*rows,rows 對應某一頁的資料
// -- countsql=select COUNT(1) from (sql)t; 符合條件的總記錄數
String pageSQL = getpageSQL(sql,pageBean);//符合條件的某一頁資料
ps = con.prepareStatement(pageSQL);
rs = ps.executeQuery();
}else {
//不分頁(select需求)
ps = con.prepareStatement(sql);//符合條件的所有資料
rs = ps.executeQuery();
}
while (rs.next()) {
T t = clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
list.add(t);
}
return list;
}
/**
* 將原生sql轉換成countsql
* @param sql
* @return
*/
private String getcountSQL(String sql) {
//countsql=select COUNT(1) from (sql)t;符合條件的總記錄數
return "select count(1) from ("+sql+") t";
}
/**
* 將原生SQL轉換成pageSQL
* @param sql
* @param pageBean
* @return
*/
private String getpageSQL(String sql,PageBean pageBean) {
//(this.page - 1) * this.rows;
//sql:原生sql (page-1)*rows:起始下標 rows:多少頁
//pagesql=sql limit (page-1)*rows,rows
return sql +" limit "+ pageBean.getStartIndex() +","+pageBean.getRows();
}
}
3.BookDao—書籍dao層類
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.hpw.util.DBAccess;
import com.hpw.util.PageBean;
import com.hpw.util.StringUtils;
import entity.Book;
public class BookDao extends BaseDao<Book>{
/**
*
* 簡單的查詢方法 (思路)
* 1.建立資料庫連接
* 2.預定義物件PrepareStatement
* 3.查詢結果集
* 4.處理結果集
*
* 不足之處
* 換一張表查詢 t_jsoup_article
* 1.以上三步 (建立資料庫連接 ,預定義物件PrepareStatement,查詢結果集 )都是重復的
* 2.都是回傳資料庫表對應的集合
* 3.都是要處理結果集 ResultSet rs
* 代碼不一樣 具體體現在 不同的表有不同欄位 那么物體類對應的屬性就會不一樣
*
* 總結:需要寫大量的重復代碼 , 系統中的查詢功能越多 重復代碼量越大
*
* 提供解決方案
* 1.抽取變化部分作為引數
* sql ,Class物件 結果集
* 2.抽取公共的父類,把重復性的代碼剝離出來
*/
public List<Book> keylist(Book book) throws Exception {
List<Book> book1 = new ArrayList<Book>();
String sql = "select * from t_mvc_book where 1=1";
// 書籍名稱
String bname = book.getBname();
// 書籍名稱模糊查詢 是前臺jsp界面傳資料
if (StringUtils.isNotBlank(bname)) {
sql += " and bname like '%" + bname + "%' ";
}
Connection con = DBAccess.getConnection();
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
book1.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
}
return book1;
}
public List<Book> list2(Book book) throws Exception{
String sql = "select * from t_mvc_book where 1=1";
// 書籍名稱
String bname = book.getBname();
// 書籍名稱模糊查詢 是前臺jsp界面傳資料
if (StringUtils.isNotBlank(bname)) {
sql += " and bname like '%" + bname + "%' ";
}
return super.keylist(sql, Book.class);
}
/**
* 測驗通用分頁查詢
* @param book
* @param pageBean
* @return
* @throws Exception
*/
public List<Book> list3(Book book,PageBean pageBean) throws Exception{
String sql = "select * from t_mvc_book where 1=1";
// 書籍名稱
String bname = book.getBname();
// 書籍名稱模糊查詢 是前臺jsp界面傳資料
if (StringUtils.isNotBlank(bname)) {
sql += " and bname like '%"+bname+"%'";
}
return super.executeQuery(sql, Book.class, pageBean);
}
/**
* 思考:
* 在專案中大量的出現分頁的需要(訂單串列,商品串列,學生串列...)
* 目標:
* 想要做一個通用的分頁查詢,子類去繼承父類,自帶了分頁功能,并且代碼量極少;
* 最終當碰到分頁的需求的時候,只要寫少量的代碼
* 實作:
* mysql分頁
* 分頁通常有關鍵的元素 第n頁 、顯式數目(rows)、符合條件的總記錄數(total)
*-- sql=SELECT * FROM t_mvc_book WHERE bname like '%圣墟%'
-- pagesql=sql limit (page-1)*rows,rows
-- countsql=select COUNT(1) from (sql)t;
*
* 編碼:
* 2.1原先List集合中回傳的是符合條件的所有資料,現在我需要發揮第page頁的資料
* 那么意味著sql要加工成pageSql
* 2.2需要分頁,那么要求出符合條件的總記錄數,保存到pagebean中,意味著sql要加工成countSql
* 共85條資料 1頁10條 總共9頁
共70條資料 1頁10條 總共7頁
通過上面的數字,說明了要得出共n頁,那么必須求出總記錄數
共n頁的演算法 : total % rows == 0 ? total / rows :total / rows +1;
*/
public static void main(String[] args) throws Exception {
BookDao bd = new BookDao();
Book book = new Book();
book.setBname("圣墟");
//List<Book> list = bd.keylist(book);
//List<Book> list = bd.list2(book);
PageBean pageBean = new PageBean();
//查第二頁的資料 模擬從jsp傳遞頁碼2到后臺
//pageBean.setPage(2);
//專案開發中 下拉框的需求 不分頁 模擬從jsp傳遞 不分頁的資訊pagination=false
pageBean.setPagination(false);
List<Book> list = bd.list3(book, pageBean);
for (Book book2 : list) {
System.out.println(book2);
}
}
}
在父類中對key進行非空判斷是為了判斷用戶是否在輸入框中輸入值進行查詢,如果點擊下一頁之類的操作,key是上一次查詢請求的值,改變的只是頁碼引數,由PageBean這個類對上一次請求引數進行保存,
4.PageBean—分頁工具類
package com.hpw.util;
import java.io.StringBufferInputStream;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.sun.net.httpserver.HttpServer;
/**
* 分頁工具類
*
*/
public class PageBean {
private int page = 1;// 頁碼
private int rows = 10;// 頁大小
private int total = 0;// 總記錄數
private boolean pagination = true;// 是否分頁
private String url;// 保存上一次請求的URL
private Map<String, String[]> paramMap = new HashMap<String, String[]>();// 保存上一次請求的引數
/**
* 初始化pagebean ,保存上一次請求的重要引數
*/
public void setRequest(HttpServletRequest req) {
// 1.1需要保存上一次請求的URL
this.setUrl(req.getRequestURL().toString());
// 1.2需要保存上一次請求的引數
this.setParamMap(req.getParameterMap());
// 1.3需要保存上一次請求的分頁設定
this.setPagination(req.getParameter("pagination"));
// 1.4需要保存上一次請求的展示條數
this.setRows(req.getParameter("rows"));
// 1.5初始化的頁碼
this.setPage(req.getParameter("page"));
}
public void setPage(String page) {
// TODO Auto-generated method stub
if(StringUtils.isNotBlank(page)) {
this.setPage(Integer.valueOf(page));
}
}
public void setRows(String rows) {
// TODO Auto-generated method stub
if(StringUtils.isNotBlank(rows)) {
this.setRows(Integer.valueOf(rows));
}
}
public void setPagination(String pagination) {
// TODO Auto-generated method stub
// 只有在前臺jsp填寫了pagination=false,才代表不分頁
if(StringUtils.isNotBlank(pagination)) {
this.setPagination(!"false".equals(pagination));
}
}
public void setPagination(boolean pagination) {
this.pagination = pagination;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, String[]> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String[]> paramMap) {
this.paramMap = paramMap;
}
public PageBean() {
super();
}
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 void setTotal(String total) {
this.total = Integer.parseInt(total);
}
public boolean isPagination() {
return pagination;
}
/**
* 獲得起始記錄的下標
*
* @return
*/
public int getStartIndex() {
return (this.page - 1) * this.rows;
}
/**
* 最大頁
*
* @return
*/
public int maxPage() {
return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows + 1;
}
/**
* 下一頁
*/
public int nextPage() {
// 如果當前頁小于最大頁,那就下一頁為當前頁加一,如果不小于,說明當前頁就是最大頁,那就無需加一
return this.page < this.maxPage() ? this.page + 1 : this.page;
}
/**
* 上一頁
*
* @return
*/
public int previousPage() {
return this.page > 1 ? this.page - 1 : this.page;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
}
}
三.前端
有了前端通用分頁,在每一個頁面中如果需要分頁,僅僅需要在jsp界面中撰寫我們自己定義好的分頁標簽,將重復代碼都提取到了標簽助手類中,
1.tld檔案
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>hpw 1.1 core library</description>
<display-name>hpw core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>hpw</short-name>
<uri>http://hpw11.myjsp</uri>
<tag>
<name>page</name>
<tag-class>com.hpw.tag.pageTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>pageBean</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
2.pageTag助手類
package com.hpw.tag;
import java.io.IOException;
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.hpw.util.PageBean;
public class pageTag extends BodyTagSupport {
private PageBean pageBean;// 包含了所有分頁相關的元素
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
@Override
public int doStartTag() throws JspException {
// TODO Auto-generated method stub
// 沒有標簽體,要輸出內容
JspWriter out = pageContext.getOut();
try {
out.print(toHTML());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return super.doStartTag();
}
private String toHTML() {
StringBuffer sb = new StringBuffer();
// 隱藏的form表單 這個就是上一次請求下次重新發的奧義所在
sb.append(" <form action='" + pageBean.getUrl() + "' id='pageBeanForm' method='post'>");
sb.append(" <input type='hidden' name='page'>");
// 上一次請求的引數
Map<String, String[]> paramMap = pageBean.getParamMap();
if (paramMap != null && paramMap.size() > 0) {
Set<Entry<String, String[]>> entrySet = paramMap.entrySet();
for (Entry<String, String[]> entry : entrySet) {
// 引數名
String key = entry.getKey();
// 引數值
for (String value : entry.getValue()) {
// 上一次的請求的引數,再一次組裝成了新的form表單
// 注意:page引數每次都會提交
if (!"page".equals(key)) {
sb.append(" <input type='hidden' name='" + key + "' value='" + value + "'>");
}
}
}
}
sb.append("</form>");
// 分頁條
sb.append(" <ul class='pagination justify-content-center'>");
sb.append(" <li class='page-item " + (pageBean.getPage() == 1 ? "disabled" : "") + "'><a class='page-link'");
sb.append(" href='javascript:gotoPage(1)'>首頁</a></li>");
sb.append(" <li class='page-item " + (pageBean.getPage() == 1 ? "disabled" : "") + "'><a class='page-link'");
sb.append(" href='javascript:gotoPage(" + pageBean.previousPage() + ")'><</a></li>");
// sb.append(" <li class='page-item'><a class='page-link' href='#'>1</a></li>");
// sb.append(" <li class='page-item'><a class='page-link' href='#'>2</a></li>");
sb.append(" <li class='page-item active'><a class='page-link' href='#'>" + pageBean.getPage() + "</a></li>");
sb.append(" <li class='page-item " + (pageBean.getPage() == pageBean.maxPage() ? "disabled" : "")
+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.nextPage() + ")'>></a></li>");
sb.append(" <li class='page-item " + (pageBean.getPage() == pageBean.maxPage() ? "disabled" : "")
+ "'><a class='page-link' href='javascript:gotoPage(" + pageBean.maxPage() + ")'>尾頁</a></li>");
sb.append(" <li class='page-item go-input'><b>到第</b><input class='page-link'");
sb.append(" type='text' id='skipPage' name='' /><b>頁</b></li>");
sb.append(" <li class='page-item go'><a class='page-link'");
sb.append(" href='javascript:skipPage()'>確定</a></li>");
sb.append(" <li class='page-item'><b>共" + pageBean.getTotal() + "條</b></li>");
sb.append("</ul>");
// 分頁執行的jsp代碼
sb.append("<script type='text/javascript'>");
sb.append(" function gotoPage(page) {");
sb.append(" document.getElementById('pageBeanForm').page.value = page;");
sb.append(" document.getElementById('pageBeanForm').submit();");
sb.append(" }");
sb.append(" function skipPage() {");
sb.append(" var page = document.getElementById('skipPage').value;");
sb.append(
" if (!page || isNaN(page) || parseInt(page) < 1 || parseInt(page) > " + pageBean.maxPage() + ") {");
sb.append(" alert('請輸入1~" + pageBean.maxPage() + "的數字');");
sb.append(" return;");
sb.append(" }");
sb.append(" gotoPage(page);");
sb.append(" }");
sb.append(" </script>");
return sb.toString();
}
}
3.前端界面 index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://hpw11.myjsp" prefix="p"%>
<%@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">
<link
href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
rel="stylesheet">
<script
src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
<title>書籍串列</title>
<style type="text/css">
.page-item input {
padding: 0;
width: 40px;
height: 100%;
text-align: center;
margin: 0 6px;
}
.page-item input, .page-item b {
line-height: 38px;
float: left;
font-weight: 400;
}
.page-item.go-input {
margin: 0 10px;
}
</style>
</head>
<body>
<form class="form-inline"
action="${pageContext.request.contextPath }/book.action" method="post">
<div class="form-group mb-2">
<input type="text" class="form-control-plaintext" name="bname"
placeholder="請輸入書籍名稱">
</div>
<button type="submit" class="btn btn-primary mb-2">查詢</button>
</form>
<table class="table table-striped bg-success">
<thead>
<tr>
<th scope="col">書籍ID</th>
<th scope="col">書籍名</th>
<th scope="col">價格</th>
</tr>
</thead>
<tbody>
<c:forEach var="b" items="${books }">
<tr>
<td>${b.bid }</td>
<td>${b.bname }</td>
<td>${b.price }</td>
</tr>
</c:forEach>
</tbody>
</table>
<a href="${pageContext.request.contextPath }/book/add">新增</a>
<p:page pageBean="${pageBean }"></p:page>
</body>
</html>
效果展示:

下面的分頁在jsp界面僅用一行就能完成,其他界面還需要也一樣,不用每個界面再寫HTML和JS來實作這個分頁條的效果!重復代碼,能有這些效果完全少不了PageBean物件!!!
四.Servlet
package com.hpw.web;
import java.io.IOException;
import java.util.List;
import java.util.Map;
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 com.hpw.util.PageBean;
import dao.BookDao;
import entity.Book;
@WebServlet("/book/search")
public class BookServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 目標:
* 痛點:每次做分頁需求的時候,都會有大量的重復的后臺代碼,以及前臺代碼
* 后臺代碼重復問題已解決
* 前臺重復代碼問題
* 1.大量的前臺html重復
* 2.大量的javaScript代碼
* 目標:
* 定義一個標簽
* <h:page><h:page>
* 無需寫任何的html以及js,就可以完成前端分頁
* 分析:
* 1. 前臺分頁 后一次請求相較于上一次只不過是頁碼改變了
* 1.1需要保存上一次請的的URL
* 1.2需要保留上一次請求的引數
* 1.3需要保存上一頁的分頁設定 pagination
* 1.4需要保存上一次的展示條目數
* 1.5初始化請求的頁碼 page
* 2.開發自定義jsp標簽(page標簽)
* 定義pagebean 因為pagebean中包含了分頁中所有的元素 (page/rows/pagination/total/nexPage/previouPage/maxPage)
*
* 前臺jsp傳遞書名圣墟 , 后臺接收 req.getParameter("bname")
* 愛好:傳遞一個陣列 藍球,足球...hobby String[] hobbys = req.getParameterValues("")
*
* bname String 這個陣列長度是為1的
* hobby String [] 可能會有很多個
* ...
* 本方法的作用是接收jsp頁面傳遞到后臺的引數值鍵值對,也就是把parameteMap遍歷,可以拿到bname以及hobby
Map<String, String[]> parameteMap = req.getParameterMap();
*/
BookDao bookDao=new BookDao();
Book book=new Book();
book.setBname(req.getParameter("bname"));
PageBean pageBean=new PageBean();
pageBean.setRequest(req);
try {
List<Book> list3 = bookDao.list3(book, pageBean);
req.setAttribute("books", list3);
req.setAttribute("pageBean", pageBean);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
req.getRequestDispatcher("/index.jsp").forward(req, resp);
//本方法的作用是接收jsp頁面傳遞到后臺的引數值鍵值對,也就是把parameteMap遍歷,可以拿到bname以及hobby
// Map<String, String[]> parameteMap = req.getParameterMap();
}
}
前端用戶發送請求進過我們的一系列處理之后回傳一個符合用戶請求的前端頁面呈現!!!帶著這個流程去查看學習對應地方的代碼,
這里的核心是PageBean,它幾乎每個流程都在,它由用戶需求決定,然后決定資料,再決定分頁條!!!
到這里就結束了,我依舊是那個學IT的小學生
歡迎大佬指點
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297812.html
標籤:其他
下一篇:課程后臺管理系統
