关注分享主机优惠活动
国内外VPS云服务器

全栈通用分页查询(分页查询实现)

总结:简介说明了全栈通用分页查询码字是多么的困难。 如果点击下面转载,请描述一下开发者工具、思维导图目录1、所需包2、后端数据库、帮助类、通用查询分页、父类、书层类分页。 工具类别 3 前端文件助手类别 前端接口 41 所需包 2 后端数据库

前言:我们来谈谈全栈通用分页查询

代码 请注意,语言很难。 。

转载时请提供说明。

开发工具:eclipse

思维导图:

目录

1、所需jar包

2.后端

1.数据库帮助类

2.BaseDao ——通用查询分页父类

3 .BookDao — Book dao 层类

4.PageBean-分页工具类

3.前端

1.tld 文件

2.pageTag 辅助类

3.前端界面index.jsp

4.Servlet

1、需要的jar包

p> 2. 后端 1. 数据库帮助程序类

DBAccess — 数据库帮助程序类

package com.hpw.util;import java.io.InputStream;导入 java.sql.Connection;导入 java.sql.DriverManager;导入 java.sql.ResultSet;导入 java.sql.SQLException;导入 java.sql.Statement;导入 java.util.Properties;/** * 提供 A用于检索或关闭数据库对象的方法集* */public class DBAccess {private static String driver;private static String url;private static String user;private static String Password;static {//静态块一次它将运行并且驱动程序将被加载一次。 尝试一下。 .getProperty("url ");user = property.getProperty("user");password = property.getProperty("pwd");Class.forName(driver);} catch (例外 e) {e.printStackTrace(); throw new RuntimeException(e );}}/** * 获取数据连接对象 * * @return */public staticConnection 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();抛出新的 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) {连接 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#mysql8driver=com.mysql.cj.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=trueuser =rootpwd=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—编码过滤器类

包 com.hpw.util;import java.io.IOException;import java.util.Iterator;import java.util.Map;import java.util.Set;import javax. servlet.Filter;导入 javax.servlet.FilterChain;导入 javax.servlet.FilterConfig;导入t javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 中文乱码* * /public class EncodingFiterimplements Filter {private String编码 = "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. + this.encoding);if (req.getMethod().equalsIgnoreCase("post")) {req.setCharacterEncoding(this.encoding);} else{Map Map = req.getParameterMap(); // 保存所有参数名称的Map集合 = 参数值(array) 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 < value.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—通用查询分页父类包 dao;import java. .Field;导入java.sql.Connection;导入java.sql.PreparedStatement;导入java.sql.ResultSet;导入java.util.ArrayList;导入java.util。List;import com.hpw.util.DBAccess;import com.hpw.util.PageBean;import com.hpw.util.StringUtils;importentity.Book;public class BaseDao {/** * 下面是所有 Dao 层的父类提供解决方案 解决方案 1.提取变化的部分作为参数sql的结果集,类对象。 2. 提取public父类,去掉重复代码* * @param */public List keylist(String sql, Class clz) throws Exception {// 无法确定集合包含什么 // 子类Dao会继承该类。 BaseDao 子类传递的类以及将放置在集合中的内容 List list = new ArrayList();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[] field = clz.getDeclaredFields();for (field f : field) {f.setAccessible(true);f .set( t, rs.getObject(f.getName()));} list.add(t);}rreturn list; }/** * 一般分页查询 * * @param sql * @param clz * @return * @throws exception */public ListexecuteQuery(String sql, Class clz,PageBean pageBean) throws Exception {List list = new ArrayList ( );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)));} //返回的结果集会最后处理,所以转到end // 必须分页(列表要求) // *-- sql=SELECT * FROM t_mvc_book WHERE bname like "%圣IX%" // -- Pagesql=sql limit (page- ]1 )*rows,rows对应一页的数据 // -- countsql=select COUNT(1) from (sql)t; 满足条件S的记录总数tring pageSQL = getpageSQL(sql,pageBean);//符合条件的数据分页 ps = con.prepareStatement(pageSQL);rs = ps.executeQuery();}else {//不分页(选择要求) ps = con .prepareStatement(sql);//满足条件的所有数据 rs = ps.executeQuery();}while (rs.next()) {T t = clz.newInstance();Field[] field = clz.getDeclaredFields( ) ;for (field f : field) {f.setAccessible(true);f.set(t, rs.getObject(f.getName()));}list.add(t);}返回列表;}/ * * * 将原生SQL转换为countsql * @param sql * @return */private String getcountSQL(String sql) {//countsql=select COUNT(1) from (sql)t;返回满足条件的记录总数。 "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: 下标起始行: 页数 //pagesql=sql limit (page[ k4] ]1)*rows,rows return sql +" limit "+ pageBean.getStartIndex() +","+pageBean.getRows();}} 3.BookDao—Book dao层类包 dao;import java.sql.Connection;import java.sql.PreparedStatement;导入 java.sql.ResultSet;导入 java.sql.SQLException;导入 java.util.ArrayList;导入 java.util.List;导入 com.hpw.util.DBAccess;导入 com.hpw.util。 PageBean;import com.hpw.util.StringUtils;importentity.Book;public class BookDao extends BaseDao{/** * * 简单查询方法(思路) * 1.建立数据库连接 * 2.预定义对象PrepareStatement * 3.查询结果Set* 4. 处理结果集* * 缺点* 改表查询t_jsoup_article * 1. 上面三个步骤(建立数据库连接、定义对象PrepareStatement、查询结果集)全部重复 * 2. 都要处理ResultSet rs对应数据库表 * 3.他们都要处理结果集 ResultSet rs * 代码上的区别体现在每个表的字段不同,所以实体类对应的属性也不同* * 总结:我们需要写很多重复的代码,而且系统中的查询功能越多,重复代码量就越多 * * 提供了解决方案 * 1 . 将变化的部分提取为参数 * sql、类对象结果set * 2.提取公共代码父类,去掉重复代码 */public List keylist(Book book) throws Exception {List book1 = new ArrayList();String sql = "select * from t_mvc_book where 1=1";//书名 String bname = book. ();//书名模糊查询是前端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 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 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);}/** *观察: *项目有很多分页需求(有序列表、产品列表、学生列表) list...) * 目标: * 如果要创建通用的分页查询,子类应该继承父类,并有自己的分页功能,代码量会很小。 * 最终,当出现分页需求时,只需要编写少量代码即可。 * 实现: * mysql 分页 * 分页通常有以下关键元素:页n、显式编号(行)以及匹配记录总数。 条件(总计) *-- sql=SELECT * FROM t_mvc_book WHERE bname like "%Shenzhen%" -- Pagesql=sql limit (page-1)*rows,rows - [ k4]从countsql=(sql)t中选择COUNT(1)。 * * 编码: * 2.1 原始列表集合返回所有满足条件的数据。 现在我们需要回放页面上的数据*那么就意味着需要将SQL处理成pageSql * 2.2需要分页。 接下来,我们需要满足条件的记录总数,该记录存储在 pagebean 中。 即我们需要处理的SQL countSql * Total 85。 数据为1页10张,共9页,共70张。 有1页数据,10条记录,共7页。 上面的数字表明,要得到总共n页,我们需要使用一种算法来求出记录总数和n页总数。 总计 % 行 == 0 ? 总计 / 行 :总计 / 行 + 1 */public static void main(String[] args) 抛出异常 {BookDao bd = new BookDao();Book book = new Book();book. setBname("圣行");//列表 list = bd. key list (book); //List list = bd.list2(book);PageBean pageBean = new PageBean();//查看第二页的数据,模拟从jsp传递页码2到后台我会的。 //pageBean.setPage(2); //项目开发中下拉框的一个需求是模拟从非分页JSP发送非分页信息 pagination=falsepageBean.setPagination(false) ;List list = bd.list3(book , pageBean);for (Book book2 : list) { 系统 . out.println(book2);}}}

对父类键的非空测试确定用户是否在查询的输入框中输入了值。 当用户单击下一页或执行其他操作时,键是上一页。 查询请求的值仅改变页码参数。 页码参数由PageBean 类修改。保存请求参数。

4.PageBean—分页工具类包 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 paramMap = new HashMap() // 保存上次请求的参数 /** * 初始化并保存页面bean 请求的重要参数 * /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.获取参数("行数"));// 1.5 初始化页码 this.setPage(req.getParameter("page"));} public void setPage(String page) {// TODO自动-生成方法stubif(StringUtils.isNotBlank (page) ) {this.setPage(Integer.valueOf(page));}} public void setRows(String rows) {// TODO 自动-生成方法 Stubif(StringUtils.isNotBlank(rows)) {this.setRows( Integer.valueOf ) (rows));}}public void setPagination(String pagination) {//TODO 自动 - 生成的方法存根 // 仅当在前端 JSP 中输入 pagination=false 时才可能进行分页 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 getParamMap() {return paramMap;}public void setParamMap(Map paramMap) {this.paramMap = paramMap;}public PageBean() {super();}public int getPage() {返回页面;}public void setPage(int page) {this.page = page;}public int getRows() {返回行;}公共无效setRows(int行){this.rows =行;}公共int getTotal(){返回总计;}公共无效setTotal(int总计){this.total =总计;}公共无效setTotal(字符串总计){this。 Total = Integer.parseInt(total);}public boolean isPagination() {return pagination;}/** * 获取起始记录索引* * @return */public int getStartIndex() {return (this.page [k4 ] 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() {// 如果当前页小于最大页,则下一页为当前页加1。 如果不小于,则添加当前页面。 由于这是最大页面,因此不需要添加 return this.page 1 ? this.page - 1 : this.page;}@Overridepublic String toString() { return "PageBean [page="+page+",rows="+rows+",total="+total+",pagination="+pagination+"]";}} 3.前端

前端与通用分页,如果每个页面都需要分页,只需在JSP界面中编写自己定义的分页标签即可。 将重复的代码提取到标签帮助器类中。

1.tld 文件 hpw 1.1 核心库 hpw core 1.1 hpw http://hpw11.myjsp page com.hpw.tag.pageTag JSP pageBean true true 2.pageTag 辅助类包 com.hpw.tag;import java.lang. io.IOException;导入java.util.Map;导入java.util.Map.Entry;导入java.util.Set;导入javax.servlet.jsp.JspException;导入javax.servlet.jsp.JspWriter;导入javax.servlet。 jsp.tagext.BodyTagSupport;导入com.hpw.util.PageBean;公共class pageTag extends BodyTagSupport {private PageBean pageBean;//包含所有分页相关元素 public PageBean getPageBean() {return pageBean;}public void setPageBean(PageBean pageBean) {this.pageBean = pageBean;}@Overridepublic int doStartTag( ) throws JspException { // TODO 自动 - 生成方法存根 // 无标签体,必须输出内容 JspWriter out = pageContext.getOut();try {out.print(toHTML()) ;} catch (Exception e) {// TODO :handleExceptione.printStackTrace();}return super.doStartTag();}private String toHTML() {StringBuffer sb = new StringBuffer();//隐藏表单form是上次请求的秘密,是下次重新发送的秘密 sb.append (" ");// 分页栏 sb.append(" ");sb.append("首页");sb.append(" ");sb.append("最后一页");sb. to page");sb.append("OK");sb.append("Total" + pageBean.getTotal() + "Item");sb.append("");//Jsp执行分页代码sb .append("");return sb.toString();}} 3.前端接口index.jsp图书列表.page-项目输入 {padding: 0;width: 40px;height: 100%;text-align: center;margin: 0 6px;}.page-item 输入, .page-项目 b {line-height: 38px; float: font-weight: 400;}.page-item.go-input {margin: 0 10px;} 图书 ID 图书名称 价格 $ { b.bid }${b.bname }${b.price }New

显示效果:

接下来的分页是JSP界面中的一行。就可以完成它 其他接口应该是一样的,不需要做如下的分页: 要实现这个分页栏效果,需要为每个界面编写HTML和JS。 重复的代码。 PageBean 对象对于实现这些效果是绝对必要的。 ! ! 4.Servlet包 com.hpw.web;import java.io.IOException;import java.util.List;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet ;导入 javax.servlet.http.HttpServlet;导入 javax.servlet.http.HttpServletRequest;导入 javax.servlet.http.HttpServletResponse;导入 com.hpw.util.PageBean;导入 dao.BookDao;importentity.Book;@WebServlet( " /书/套} @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /** * 目标: * 问题:每次有分页需求时,最终都会得到大量重复的不仅仅是前端代码,还有后端代码 * 解决了后端代码重复的问题 * 前端重复代码问题 * 1. 大量重复的前端 HTML * 2. 大量 JavaScript 代码 * 目标: * 定义标签 * * 前端无需任何编写HTML和JS即可完成分页 * 分析: * 1. 前端分页后的最后一个请求与前一个请求相比仅改变了页码 * 1.1 应保存最后一个请求的URL * 1.2必须保留请求参数 上次请求 * 1.3 必须保留上一页的分页设置 * 1.4 必须保留上次显示的条目数 * 1.5 必须初始化请求页码 *2. 开发自定义JSP标签(page标签) * 定义一个page bean,因为它包含分页的所有元素(page/rows/pagination/total/nexPage/previouPage/maxPage) * * 前端JSP将书名传递到后面-end 接收 req.getParameter("bname") * Hobby:传递篮球、足球... Hobby String[] Hobbys = req.getParameterValues("" ) * * bname String 这个数组的长度为1 * Hobby String [ ] Many *... * 该方法的作用是接收JSP页面传给后台的参数值和键值对。 即可以遍历parameterMap,获取bname和Hobby。 映射参数Map = req.getParameterMap() */ BookDao bookDao=new BookDao();Book book=new Book();book.setBname(req.getParameter("bname"));PageBean pageBean=new PageBean(); pageBean.setRequest(req);try {List list3 = bookDao.list3(book, pageBean);req.setAttribute("books", list3);req.setAttribute("pageBean", pageBean);} catch (例外 e) { // 待办事项自动-生成的catch blocke.printStackTrace();}req.getRequestDispatcher("/index.jsp").forward(req, resp); //该方法的功能是由JSP页面传递到后台的接收参数值键值。 是的,这意味着如果你遍历parameterMap,你可以得到bname和Hobby。 // Map parameteMap = req.getParameterMap(); }}

前端用户提交请求,经过一系列流程,返回满足用户请求的前端页面。 当前! ! ! 使用此过程来查看和学习相应位置的代码。

其核心是 PageBean,它几乎存在于每个进程中。 它是由用户的需求决定的,然后是数据,然后是分页栏。 ! !

我就到这里了,我还是个学IT的小学生

欢迎大家提出建议

未经允许不得转载:主机频道 » 全栈通用分页查询(分页查询实现)

评论 抢沙发

评论前必须登录!