通用分页

it2022-05-05  138

通用分页

通用分页核心思路 将上一次查询请求再发一次,只不过页码变了

思路 1、将原有的查询向上抽取 2、让返回值变成泛型 3、使用回调函数处理resultset 4、利用反射处理回调函数 5、获取总记录数(页面展示,计算总页数) 6、拼接分页sql语句,获取对应的结果集

一、利用反射封装出通用的查询方法:

Jar包:

MySQL数据库:

1、Util类:

1.1、连接数据库的代码:

#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 #mysql5 driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT user=mybatis_ssm pwd=xiaoli

1.2、 DBAccess连接数据库:

package com.qiuwenfan.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.jdbc.Driver".equals(driver); } public static void main(String[] args) { Connection conn = DBAccess.getConnection(); DBAccess.close(conn); System.out.println("isOracle:" + isOracle()); System.out.println("isSQLServer:" + isSQLServer()); System.out.println("isMysql:" + isMysql()); System.out.println("数据库连接(关闭)成功"); } }

1.3、中文乱码处理代码:EncodingFiter

package com.qiuwenfan.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(); } } }

1.4、分页类:PageBean

package com.qiuwenfan.util; /** * 分页工具类 * */ public class PageBean { private int page = 1;// 页码 private int rows = 10;// 页大小 private int total = 0;// 总记录数 private boolean pagination = true;// 是否分页 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; } public void setPagination(boolean pagination) { this.pagination = pagination; } /** * 获得起始记录的下标 * * @return */ public int getStartIndex() { return (this.page - 1) * this.rows; } @Override public String toString() { return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]"; } }

1.5、封装if(判断是否为空):StringUtils

package com.qiuwenfan.util; public class StringUtils { // 私有的构造方法,保护此类不能在外部实例化 private StringUtils() { } /** * 如果字符串等于null或去空格后等于"",则返回true,否则返回false * * @param s * @return */ public static boolean isBlank(String s) { boolean b = false; if (null == s || s.trim().equals("")) { b = true; } return b; } /** * 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false * * @param s * @return */ public static boolean isNotBlank(String s) { return !isBlank(s); } }

1.6、用来处理所有表的通用的增删改查的基类:BaseDao

package com.qiuwenfan.util; 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; /** * 用来处理所有表的通用的增删改查的基类 * * 查询指的是:通用的分页查询 * @author qiuwenfan * * @param <T> */ public class BaseDao<T> { /** * * @param sql 可能不同的表,那么意味着sql是变化的,那么它是从子类处理好再传递到父类 * @param clz 需要返回不同的对象集合 Book.class/Order.class * @param pageBean 可能要分页 * @return * @throws Exception */ public List<T> executeQuery(String sql, Class clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<>(); Connection con = DBAccess.getConnection(); PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = ps.executeQuery(); T t = null; while(rs.next()) { // list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price"))); /** * 1、实例化了一个book对象 * 2、通过book对象的属性名去游标中取出属性值 * 2.1、获取到类对象中的属性 * 2.2、给属性赋值 * 3、已经赋值好的book实例化对象,放入list集合中 * * clz->Book.class */ 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; } }

图片:

注:当isMySQL为true,连接成功

Entity类:

Book包:

package com.qiuwenfan.entity; public class Book { private int bid; private String bname; private float price; public Book(int bid, String bname, float price) { super(); this.bid = bid; this.bname = bname; this.price = price; } public Book() { super(); } @Override public String toString() { return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]"; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getBname() { return bname; } public void setBname(String bname) { this.bname = bname; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }

Dao类:

BookDao包:

package com.qiuwenfan.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import com.qiuwenfan.entity.Book; import com.qiuwenfan.util.BaseDao; import com.qiuwenfan.util.DBAccess; import com.qiuwenfan.util.PageBean; import com.qiuwenfan.util.StringUtils; /** * 书籍访问数据库的Dao层 * @author qiuwenfan * */ public class BookDao extends BaseDao<Book>{ /** * 第一个版本(利用s2知识完成书籍查询) * * @param book * @param pageBean * @return * @throws Exception */ // public List<Book> list(Book book, PageBean pageBean) throws Exception { // String sql = "select * from t_mvc_book where true "; // List<Book> list = new ArrayList<>(); // String bname = book.getBname(); // 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()) { // list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price"))); // } // return list; // } public List<Book> list(Book book, PageBean pageBean) throws Exception { String sql = "select * from t_mvc_book where true "; String bname = book.getBname(); if(StringUtils.isNotBlank(bname)) { sql += "and bname like '%"+bname+"%' "; } return super.executeQuery(sql, Book.class, pageBean); } public static void main(String[] arge) { BookDao bookDao = new BookDao(); Book book = new Book(); // book.setBname("圣墟"); try { List<Book> list = bookDao.list(book, null); for (Book b : list) { System.out.println(b); } } catch (Exception e) { e.printStackTrace(); } } }

查询结果:

二、通用的分页查询

PageBean: 分页三要素 page 页码 视图层传递过来 rows 页大小 视图层传递过来 total 总记录数 后台查出来

pagination 是否分页 视图层传递过来

MySQL分页代码:

– 原生收SQL

select * from t_mvc_book where bname like '%斗破%';

– 符合条件的记录数

select count(1) from (select * from t_mvc_book where bname like '%斗破%') t;

– 分页的查询语句

select * from t_mvc_book where bname like '%斗破%' limit start,offset

limit:起始小标,偏移量 start:查询数据集的起始下标 offset:查询展示在当前页的记录

BaseDao代码:

package com.qiuwenfan.util; 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; /** * 用来处理所有表的通用的增删改查的基类 * * 查询指的是:通用的分页查询 * @author qiuwenfan * * @param <T> */ public class BaseDao<T> { /** * * @param sql 可能不同的表,那么意味着sql是变化的,那么它是从子类处理好再传递到父类 * @param clz 需要返回不同的对象集合 Book.class/Order.class * @param pageBean 可能要分页 * @return * @throws Exception */ public List<T> executeQuery(String sql, Class clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<>(); Connection con = DBAccess.getConnection(); PreparedStatement ps = null; ResultSet rs = null; if(pageBean != null && pageBean.isPagination()) { // 分页代码 /* * 1、分页是与pagebean中total,意味着需要查询数据库得到total赋值给pagebean * 2、查询出符合条件的某一页的数据 */ // select count(1) from (select * from t_mvc_book where bname like '%斗破%') t String countSql = getCountSql(sql); ps = con.prepareStatement(countSql); rs = ps.executeQuery(); if(rs.next()) { pageBean.setTotal(rs.getObject(1).toString()); } // select * from t_mvc_book where bname like '%斗破%' limit start,offset String pageSql = getPageSql(sql, pageBean); ps = con.prepareStatement(pageSql); rs = ps.executeQuery(); }else { // 不分页代码 ps = con.prepareStatement(sql); rs = ps.executeQuery(); } T t = null; while(rs.next()) { // list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price"))); /** * 1、实例化了一个book对象 * 2、通过book对象的属性名去游标中取出属性值 * 2.1、获取到类对象中的属性 * 2.2、给属性赋值 * 3、已经赋值好的book实例化对象,放入list集合中 * * clz->Book.class */ 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; } private String getPageSql(String sql, PageBean pageBean) { return sql + "limit " + pageBean.getStartIndex()+ "," + pageBean.getRows(); } private String getCountSql(String sql) { return "select count(1) from ("+sql+") t"; } }

BookDao代码:

package com.qiuwenfan.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import com.qiuwenfan.entity.Book; import com.qiuwenfan.util.BaseDao; import com.qiuwenfan.util.DBAccess; import com.qiuwenfan.util.PageBean; import com.qiuwenfan.util.StringUtils; /** * 书籍访问数据库的Dao层 * @author qiuwenfan * */ public class BookDao extends BaseDao<Book>{ /** * 第一个版本(利用s2知识完成书籍查询) * * @param book * @param pageBean * @return * @throws Exception */ public List<Book> list(Book book, PageBean pageBean) throws Exception { String sql = "select * from t_mvc_book where true "; String bname = book.getBname(); if(StringUtils.isNotBlank(bname)) { sql += "and bname like '%"+bname+"%' "; } return super.executeQuery(sql, Book.class, pageBean); } public static void main(String[] arge) { BookDao bookDao = new BookDao(); Book book = new Book(); PageBean pageBean = new PageBean(); // pageBean.setPage(2);//控制查询页数 pageBean.setRows(5);//显示的条数 // pageBean.setPagination(false); //控制分页,true分页,false不分页 book.setBname("圣墟");//输入数据名 try { List<Book> list = bookDao.list(book, pageBean); for (Book b : list) { System.out.println(b); } System.out.println(pageBean); } catch (Exception e) { e.printStackTrace(); } } }

分页图片:

不分页图片:


最新回复(0)