通用分页简述

通用分页

首先我们先来实现一个普通的查询方法
然后导入需要的jar包(连接MySQL驱动包,标签库的包,反射包)
在这里插入图片描述
1:在建立一个连接数据库的帮助类

package com.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("数据库连接(关闭)成功");
	}

}

连接数据库的桥梁

#mysql5
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/tb_226?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
user=root
pwd=123

数据库内容如下,一共11214条数据
在这里插入图片描述
然后我们建立一个实体类

package com.entity;

public class Book {
	private int bid;
	private String bname;
	private float price;

	@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;
	}

}

在写一个简化代码的工具类(判断字符串是否为空)

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

}

然后实现查询方法

package com.Hc.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.entity.Book;
import com.util.DBAccess;
import com.util.PageBean;
import com.util.StringUtils;

/**
 * book 封装着jsp传递过来的查询参数
 *PageBean 决定dao层的list调用时是否分页
 */
public class BooKDao {
	public List<Book> list(Book book,PageBean pagebean) throws SQLException{
		String sql="select * from t_mvc_book where true";
		String bname=book.getBname();
		//判断是否模糊查询
		//调用isNotBlank方法 ,判断是否不为空,为空就不进入
		   if(StringUtils.isNotBlank(bname)) {
			   sql+="and bname like '%"+bname+"%'";
		   }
	     Connection con= DBAccess.getConnection();
	     PreparedStatement ps = con.prepareStatement(sql);
	     ResultSet rs=ps.executeQuery();
	     List<Book> list=new ArrayList<>();
	      while(rs.next()) {
	    	  list.add(new Book(rs.getInt("bid"),rs.getString("bname"),rs.getFloat("price")));
	      }
	      DBAccess.close(con, ps, rs);
	      return list;
	}
	    		 
	
	     public static void main(String[] args) {
			BooKDao dao=new BooKDao();
			Book book=new Book();
			try {
				List<Book> list=dao.list(book,null);
				for (Book b : list) {
					System.out.println(b);
				}
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}

成功查询出以下结果
在这里插入图片描述
然后根据bname进行一次模糊查,查询所有名字包含圣墟的,效果如下
在这里插入图片描述

然后现在有一个分页工具类
分页的三要素:
page 当前页码

rows 每页的大小

total 符合条件的总记录数 后台查出来

pagination 决定是否分页

package com.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 + "]";
	}

}

2.进行反射优化

首先写一个叫baseDao的方法

package com.util;

import java.lang.reflect.Field;
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.entity.Book;

/**
 * T代表你要对哪个实体类对应表进行分页查询,通用的
 * @author Administrator
 *
 * @param <T>
 * sql 查询不同的实体类,那么对应的sql不同,所以需要传递
 * clz    生产出不同的实体类对应的实例,然后装进list容器中返回
 * PageBean 决定是否分页
 * 
 * 
 */
public class BaseDao <T>{
		//用Class来生产book
		public List<T> executeQuery(String sql,Class clz,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
		     Connection con= DBAccess.getConnection();
		     PreparedStatement ps = con.prepareStatement(sql);
		     ResultSet rs=ps.executeQuery();
		     //传什么给什么
		     List<T> list=new ArrayList<>();
		     T t;
		      while(rs.next()) {
		     /**
		     * 1.实例化了一个book对象(该对象是空的,没有属性值)
		     * 2.取book的所有属性,然后给其赋值
		     * 2.1获取所有属性对象
		     * 2.2给属性对象赋值
		     * 3.赋完值的book对象装进list容器中
		     */
//		   list.add(new Book(rs.getInt("bid"),rs.getString("bname"),rs.getFloat("price")));
		      t = (T) clz.newInstance();
		      //获取所有的属性对象
		      Field[] fields = clz.getDeclaredFields();
		      for (Field field : fields) {
		    	  //打开访问权限
				field.setAccessible(true);
				//给属性对象赋值
				field.set(t, rs.getObject(field.getName()));
			}
		      //赋完值的book对象装进list容器中
		      list.add(t);
		      
		      }
		      DBAccess.close(con, ps, rs);
		      return list;
		}
}

然后调用baseDao的方法,比之前的简化了很多

//继承baskdao,操作什么传什么
public class BooKDao extends BaseDao<Book> {
	public List<Book> list(Book book,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
		String sql="select * from t_mvc_book where true";
		String bname=book.getBname();
		//判断是否模糊查询
		//调用isNotBlank方法 ,判断是否不为空,为空就不进入
		   if(StringUtils.isNotBlank(bname)) {
			   sql+=" and bname like '%"+bname+"%'";
		   }
	      return super.executeQuery(sql, Book.class, pagebean);
	}
	    		 
	
	     public static void main(String[] args) {
			BooKDao dao=new BooKDao();
			Book book=new Book();
//			book.setBid(1);
//			book.setBname("圣墟");	
			try {
				List<Book> list=dao.list(book,null);
				for (Book b : list) {
					System.out.println(b);
				}
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
	}
	

效果一样
在这里插入图片描述

3.进行分页

在baseDao进行优化

package com.util;

import java.lang.reflect.Field;
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.entity.Book;

/**

  • T代表你要对哪个实体类对应表进行分页查询,通用的
  • @author Administrator
  • @param
  • sql 查询不同的实体类,那么对应的sql不同,所以需要传递
  • clz 生产出不同的实体类对应的实例,然后装进list容器中返回
  • PageBean 决定是否分页

*/
public class BaseDao {
//用Class来生产book
public List executeQuery(String sql,Class clz,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
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(rs.getLong(1)+"");
}
//查询出符合条件的结果集
String pageSql=getPageSql(sql,pagebean);
ps = con.prepareStatement(pageSql);
rs=ps.executeQuery();

	     }else {
	    	 ps = con.prepareStatement(sql);
	    	 rs=ps.executeQuery();
	     }
	     //传什么给什么
	     List<T> list=new ArrayList<>();
	     T t;
	      while(rs.next()) {
	     /**
	     * 1.实例化了一个book对象(该对象是空的,没有属性值)
	     * 2.取book的所有属性,然后给其赋值
	     * 2.1获取所有属性对象
	     * 2.2给属性对象赋值
	     * 3.赋完值的book对象装进list容器中
	     */

// list.add(new Book(rs.getInt(“bid”),rs.getString(“bname”),rs.getFloat(“price”)));
t = (T) clz.newInstance();
//获取所有的属性对象
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
//打开访问权限
field.setAccessible(true);
//给属性对象赋值
field.set(t, rs.getObject(field.getName()));
}
//赋完值的book对象装进list容器中
list.add(t);

	      }
	      DBAccess.close(con, ps, rs);
	      return list;
	}
	/**
	 * 利用原生sql拼接处符合条件的结果集的查询sql
	 * @param sql
	 * @param pagebean
	 * @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) from  ("+sql+") t";
	}

}

在这里插入代码片

在bokkDao进行优化

package com.Hc.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.entity.Book;
import com.util.BaseDao;
import com.util.DBAccess;
import com.util.PageBean;
import com.util.StringUtils;

/**

  • book 封装着jsp传递过来的查询参数
    *PageBean 决定dao层的list调用时是否分页
    */

public class BooKDao extends BaseDao {
public List list(Book book,PageBean pagebean) throws SQLException, InstantiationException, IllegalAccessException{
String sql=" select * from t_mvc_book where true";
String bname=book.getBname();
//判断是否模糊查询
//调用isNotBlank方法 ,判断是否不为空,为空就不进入
if(StringUtils.isNotBlank(bname)) {
sql+=" and bname like ‘%"+bname+"%’";
}
return super.executeQuery(sql, Book.class, pagebean);
}

     public static void main(String[] args) {
		BooKDao dao=new BooKDao();
		Book book=new Book();

// book.setBid(1);
// book.setBname(“圣墟”);
PageBean pageBean = new PageBean();
// pageBean.setPage(2);
try {
List list=dao.list(book,pageBean);
for (Book b : list) {
System.out.println(b);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}


结果如下,默认查第一页
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190620175449451.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ1MTc3Mzcx,size_16,color_FFFFFF,t_70)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值