目录
前言:通用分页的原意义:能够简化分页相关功能的开发
目的:极大优化代码
分页代码比较:
原有的分页代码:
1.存在大量重复分页条的HTML代码
2.将上一次的查询条件带到下一次,隐藏的from表单HTML
3.后台有大量的代码是重复的
1.按原始方式写一个查询
存在问题:①有重复代码
②分页参数不清晰
解决方案:①baseDao ②pagebean
2.BaseDao
存在问题:
不同人调用,处理resultset方式是不一样的解决方案:通过回调函数解决 callback
3.callback
4.通用分页
原始SQL:调用方拼装好的sql
分页sql:页面要展示数据的sql,第N也的数据
符合条件的总记录数sql:时为了拿到总录数,计算总页数
首先把该有的文件放到util包里面
<如图所示>
分析:DBAccess为数据库辅助类
EncodingFiter为中文乱码处理
PageBean为分页的工具类
StringUtils为判空

1.为什么封装
方便使用
2.封装的优点
精简代码
《代码演示》
- package com.dengxiyan.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 + "]";
- }
-
- }
《代码演示》
BaseDao反射类
- package com.dengxiyan.util;
-
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.util.ArrayList;
- import java.util.List;
-
- import com.dengxiyan.entity.Book;
- /**
- * T代表的是实体类,可以是book/user/...
- * @author DXY
- *
- * @param <T>2022年6月21日下午7:31:26
- */
- public class BaseDao<T> {
-
- /*public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callBack) throws Exception{
- // SELECT * FROM 'tb_book' WHERE bname like '%哈哈哈%';
- //从上面得到SELECT COUNT(1) as n FROM (SELECT * FROM tb_book WHERE bname LIKE '%哈哈哈%') t;
- //目的是为了得到总记录数---->总目的是得到总页数
- *//**
- * 1.拿到数据库连接
- * 2.拿到preparstatement
- * 3.执行sql语句
- *//*
- Connection con = DBAccess.getConnection();//重复代码1
- PreparedStatement ps = con.prepareStatement(sql);//重复代码2
- ResultSet rs = ps.executeQuery();//重复代码3
- while(rs.next()) {
- ls.add(new Book(rs.getInt(bid),rs.getString("bname"),rs.getFloat("price")));
- }
-
-
- //查询不同的表,必然要处理不同的结果集
- //接口是调用方实现
- return callBack.foreach(rs);
- }*/
-
- public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callBack) throws Exception{
- // SELECT * FROM 'tb_book' WHERE bname like '%哈哈哈%';
- //从上面得到SELECT COUNT(1) as n FROM (SELECT * FROM tb_book WHERE bname LIKE '%哈哈哈%') t;
-
- //目的是为了得到总记录数---->总目的是得到总页数
- /**
- * 1.拿到数据库连接
- * 2.拿到preparstatement
- * 3.执行sql语句
- */
- Connection con = null;//重复代码1
- PreparedStatement ps = null;//重复代码2
- ResultSet rs = null;//重复代码3
- if(pageBean !=null && pageBean.isPagination()) {
- String countSql = getCountSql(sql);
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(countSql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- if(rs.next()) {
- //因为下面Sql语句里有个n 将n放进以下代码
- //pageBean(当前实体类)就包含了总记录数
- pageBean.setTotal(rs.getString("n"));
- }
- String pageSql = getpageSql(sql,pageBean);
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(pageSql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- }
- else {
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(sql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- }
- return callBack.foreach(rs);
- }
-
-
- /**
- * 拼装第n页的数据的sql
- * @return
- */
- private String getpageSql(String sql,PageBean pageBean) {
- // TODO Auto-generated method stub
- return sql + " limit "+pageBean.getStartIndex() + ","+pageBean.getRows();
- }
-
- /**
- * 拼装符合条件总记录数的sql
- * @param sql
- * @return
- */
- private String getCountSql(String sql) {
- // TODO Auto-generated method stub
- return "select count(1) as n from ("+sql+") t";
- }
-
- }
在实体类的数据访问层继承BaseDao(反射类)
《代码演示》
代码分析:
如果没有bname的值,此处的sql语句也没条件,执行时固然会报错,所以以上sql语句要加where 1=1
sql += " and bid =" +bid;
所以下面的这条sql语句要加上where 1=1 ,这样不管放哪个条件都不会报错
String sql = "select * from tb_book where 1=1 ";
- package com.dengxiyan.dao;
-
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Comparator;
- import java.util.List;
- import java.util.TreeSet;
-
- import com.dengxiyan.entity.Book;
- import com.dengxiyan.util.BaseDao;
- import com.dengxiyan.util.DBAccess;
- import com.dengxiyan.util.PageBean;
- import com.dengxiyan.util.StringUtils;
-
- public class BookDao extends BaseDao<Book>{
-
-
- /**
- * 以前阶段版本
- * @param book
- * @param pageBean
- * @return
- * @throws Exception
- */
- public List<Book> list(Book book,PageBean pageBean) throws Exception{
- List<Book> list = new ArrayList<Book>();
- /**
- * 1.拿到数据库连接
- * 2.拿到preparstatement
- * 3.执行sql语句
- */
- Connection con = DBAccess.getConnection();//重复代码1
- String sql = "select * from tb_book where 1=1 ";
- String bname = book.getBname();
- //isNotBlank(bname)不为空
- if(StringUtils.isNotBlank(bname)) {
- sql +=" and bname like '%"+bname+"%'";
- }
- int bid = book.getBid();
- //int类型的默认值为0
- if(bid!=0) {
- sql += " and bid =" +bid;
- }
- PreparedStatement ps = con.prepareStatement(sql);//重复代码2
- ResultSet rs = ps.executeQuery();//重复代码3
- while(rs.next()) {
- list.add(new Book(rs.getInt(bid),rs.getString("bname"),rs.getFloat("price")));
- }
- return list;
- }
-
-
-
-
- /**
- * 后期阶段第一版本
- * @param book
- * @param pageBean
- * @return
- * @throws Exception
- */
- public List<Book> list2(Book book,PageBean pageBean) throws Exception{
-
- List<Book> ls = new ArrayList<Book>();
- /**
- * 1.拿到数据库连接
- * 2.拿到preparstatement
- * 3.执行sql语句
- */
- String sql = "select * from tb_book where 1=1 ";
- String bname = book.getBname();
- if(StringUtils.isNotBlank(bname)) {
- sql +=" and bname like '%"+bname+"%'";
- }
- int bid = book.getBid();
- if(bid!=0) {
- sql += " and bid =" +bid;
- }
-
-
- TreeSet<String> treeSet = new TreeSet<String>((x,y)->{
- return x.compareTo(y);
- });
-
- /**
- * 简单方式
- */
- return super.executeQuery(sql, pageBean, rs ->{
- List<Book> list = new ArrayList<Book>();
- try {
- while(rs.next()) {
- ls.add(new Book(rs.getInt(bid),rs.getString("bname"),rs.getFloat("price")));
- }
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return list;
- });
- }
-
-
-
- //增删改查junit
-
- // public static void main(String[] args) throws Exception {
- // List<Book> list = new BookDao().list(new Book(), null);
- // for (Book book : list) {
- // System.out.println(book);
- // }
- // }
- }
《效果图》
前期编码版本效果图

《代码演示》
- package com.dengxiyan.util;
-
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.util.ArrayList;
- import java.util.List;
-
- import com.dengxiyan.entity.Book;
- /**
- * T代表的是实体类,可以是book/user/...
- * @author DXY
- *
- * @param <T>2022年6月21日下午7:31:26
- */
- public class BaseDao<T> {
- public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callBack) throws Exception{
- // SELECT * FROM 'tb_book' WHERE bname like '%哈哈哈%';
- //从上面得到SELECT COUNT(1) as n FROM (SELECT * FROM tb_book WHERE bname LIKE '%哈哈哈%') t;
- //目的是为了得到总记录数---->总目的是得到总页数
- /**
- * 1.拿到数据库连接
- * 2.拿到preparstatement
- * 3.执行sql语句
- */
- Connection con = null;//重复代码1
- PreparedStatement ps = null;//重复代码2
- ResultSet rs = null;//重复代码3
- if(pageBean !=null && pageBean.isPagination()) {
- String countSql = getCountSql(sql);
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(countSql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- if(rs.next()) {
- //因为下面Sql语句里有个n 将n放进以下代码
- //pageBean(当前实体类)就包含了总记录数
- pageBean.setTotal(rs.getString("n"));
- }
- String pageSql = getpageSql(sql,pageBean);
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(pageSql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- }
- else {
- con = DBAccess.getConnection();//重复代码1
- ps = con.prepareStatement(sql);//重复代码2
- rs = ps.executeQuery();//重复代码3
- }
- return callBack.foreach(rs);
- }
-
-
- /**
- * 拼装第n页的数据的sql
- * @return
- */
- private String getpageSql(String sql,PageBean pageBean) {
- // TODO Auto-generated method stub
- return sql + " limit "+pageBean.getStartIndex() + ","+pageBean.getRows();
- }
-
- /**
- * 拼装符合条件总记录数的sql
- * @param sql
- * @return
- */
- private String getCountSql(String sql) {
- // TODO Auto-generated method stub
- return "select count(1) as n from ("+sql+") t";
- }
- }
《效果图》

就相当于一个测试类
创建方式如下:

勾选 Junit4
根据实际情况勾选
《代码演示》
- package com.dengxiyan.dao;
-
- import static org.junit.Assert.*;
-
- import java.util.List;
-
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
-
- import com.dengxiyan.entity.Book;
- import com.dengxiyan.util.PageBean;
- /**
- * 作用:
- * 能够针对单个方法进行测试,相对于main方法而言,测试耦合性降低了
- * @author DXY
- *2022年6月21日下午7:25:52
- */
- public class BookDaoTest {
-
- /**
- * 调用以下两个方法与 @Before @After这两个注解有关,与方法名无关
- * @throws Exception
- */
- @Before
- public void setUp() throws Exception {
- System.out.println("被测试方法执行之前调用");
- }
-
- @After
- public void tearDown() throws Exception {
- System.out.println("被测试方法执行之后调用");
-
- }
-
- @Test
- public void testList() {
- List<Book> ls;
- try {
- ls = new BookDao().list(new Book(), null);
- for (Book book : ls) {
- System.out.println(book);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public void testList2() {
- List<Book> ls;
- try {
- ls = new BookDao().list2(new Book(), null);
- for (Book book : ls) {
- System.out.println(book);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("测试代码2");
-
- }
-
- public void testList3() {
- List<Book> ls;
- try {
- Book b = new Book();
- //加条件
- b.setBname("圣墟");
- PageBean pageBean = new PageBean();
-
- pageBean.setPage(3);
- pageBean.setRows(20);
- ls = new BookDao().list2(b, pageBean);
- for (Book book : ls) {
- System.out.println(book);
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("测试代码2");
-
- }
-
-
-
- }
《运行效果图》
