分页三要素 PageBean类
建立一个PageBean类(分页工具类)
page 页码 视图层传递过来
rows 页大小 视图层传递过来
total 总记录数 后台查出来
pagination 是否分页 视图层传递过来
/**
* 分页工具类
*/
public class PageBean {
private int page = 1;// 页码
private int rows = 10;// 页大小
private int total = 0;// 总记录数
private boolean pagination = true;// 是否分页
public PageBean() {
super();
}
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 + "]";
}
}
分页
写一个Book实体类,再写一个BookDao来实现分页
第一次查满足条件的总记录数
第二次查指定页码并满足条件的记录
二次查询的条件要一致
public class BookDao extends BaseDao<Book>{//继承自BaseDao,写通用分页的类
/**
* @param book 是从jsp传递过来的参数封装成对象的作为参数查询并执行sqsl
* @param pageBean 决定是否分页
* @return
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<Book> list(Book book,PageBean pageBean) throws SQLException{
List<Book> list = new ArrayList<>();
String sql = "select * from t_mvc_book where 1=1";
if(StringUtils.isNotBlank(book.getBname())) {
sql += " and bname like '%"+book.getBname()+"%'";
}
Connection con = DBAccess.getConnection();
PreparedStatement pst = con.prepareStatement(sql);
ResultSet rs = pst.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 SQLException, InstantiationException, IllegalAccessException{
List<Book> list = new ArrayList<>();
String sql = "select * from t_mvc_book where 1=1";
if(StringUtils.isNotBlank(book.getBname())) {
sql += " and bname like '%"+book.getBname()+"%'";
}
return super.executeQuery(sql, Book.class, pageBean);
}
public static void main(String[] args) {
BookDao bookdao = new BookDao();
try {
// PageBean pageBean = new PageBean();
// pageBean.setPagination(false);//不分页
// pageBean.setPage(2);//第几页的数据
b.setBname("不死不灭");//输入查询的关键字
b.setBname("不死不灭");//输入查询的关键字
List<Book> list = bookdao.list(b, null);//查询所有
for (Book book : list) {
System.out.println(book);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
BaseDao(通用分页的类)
思路:
1、将原有的查询向上抽取
2、让返回值变成泛型
3、使用回调函数处理resultset
4、利用反射处理回调函数
5、获取总记录数(页面展示,计算总页数)
6、拼接分页sql语句,获取对应的结果集
/**
* T = Book.class
* T = Student.class
* @author tt
*
* @param <T>
*/
public class BaseDao<T> {
/**
* @param sql 决定查询那张表的数据
* @param clz 查询出来的数据封装到那个实体列中
* @param pageBean 决定是否分页
* @return
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SQLException
*/
@SuppressWarnings("resource")
public List<T> executeQuery(String sql,Class clz,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException{
List<T> list = new ArrayList<>();
Connection con = DBAccess.getConnection();
PreparedStatement pst = null;
ResultSet rs = null;
try {
if(pageBean !=null&& pageBean.isPagination()) {
//该分页了
String countSql = getCountSql(sql);
pst = con.prepareStatement(countSql);
rs = pst.executeQuery();
if(rs.next()) {
pageBean.setTotal(rs.getLong(1)+"");
}
String pageSql = getPageSql(sql,pageBean);
pst = con.prepareStatement(pageSql);
rs = pst.executeQuery();
}else {
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
}
while(rs.next()) {
// list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
/**
* 1、创建了一个Book对象
* 2、从ResultSet结果集中获取值放入Book对象中属性中
* 2.1 获得Book的属性对象
* 2.2 给属性对象赋值
* 3、将已经有值得book对象放入list集合中
*/
T t = (T) clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
field.set(t, rs.getObject(field.getName()));
}
list.add(t);
}
} finally {
DBAccess.close(con,pst,rs);
}
return list;
}
/**
* 将原生sql拼接出符合条件的某一页的数据查询sql
* @param sql
* @param pageBean
* @return
*/
private String getPageSql(String sql, PageBean pageBean) {
return sql + " limit"+pageBean.getStartIndex()+","+pageBean.getRows();
}
/**
* 用原生sql拼接查询出符合条件的记录数
* @param sql
* @return
*/
private String getCountSql(String sql) {
return "select count(1) from ("+sql+")";
}
}
–分页的查询语句
select * from t_mvc_book where bname like ‘%斗破%’ limit start,offset
start 查询数据集的起始下标
offset:查询展示在当前页的记录
limit
SQL的语句LIMIT 约束SELECT 查询数据包表时,使得SQL查询语句返回指定的记录数(行数)。LIMIT 可以设置1个或2个int整型常量数字作为参数。
IMIT在数据分页查询时候十分有用,因为不是每一次查询都需要查询所有。
IMIT设置两个参数时候,前一个参数表示偏移,后一个表示最多查出的数据条数。
比如常见的:
ELECT * FROM table LIMIT 0,-1
LIMIT后的第一个参数0限定偏移量,后面的-1表示数据库表中最后一条数据,因为SQL中id是从1开始,所以返回了全部数据行。
(一)LIMIT n即为LIMIT 0,n
举例:SELECT * FROM table LIMIT 10
查出10条数据行,由于没有设置偏移量,那么就使用默认偏移量0,这10条数据id为:1,2,3,4,5,6,7,8,9,10
可以认为LIMIT n即为LIMIT 0,n
(二)LIMIT pos,count。
pos为前置开始的id偏移位置(不是开始位置)
举例:SELECT * FROM table LIMIT 3,10
第一个参数偏移量为3,从id=4开始,查出10条数据,这10条数据id为:4,5,6,7,8,9,10,11,12,13