分页的实现

最近用了一下EasyUI的分页插件,感觉用起来简单,只需要传给它两个参数rows和total就行,但是之前并不知道它的实现原理,所以学的时候还是挺不容易的。
现在了解了一下它的实现原理,之前的困惑就再也不在了。

首先,来分析一下:

在这里插入图片描述
我要实现的效果如图,在这里并不使用JS、Ajax或框架等工具,就用原生的servlet和jdbc来实现
先看最下面一行的实现:
数据的总条数:
这个简单,用一条sql查询就行了,语句如下:

select count(*) from mytable

(页面容量)每页显示的条数:
这里已经固定为5条

总页数
先判断能否整除,判断值 = 总条数 / 页面容量
若能整除, 总页数 = 总条数 / 页面容量
不能整除,则 总页数 = 总条数 / 页面容量+1

当前页码
开始时默认为1,每次用户向后台发送请求要换页时,前台就会向后台发送一个请求参数relocate,此参数的值为当前页码±1,从而定位到要跳转的页数

跳转:
当我们点击下一页时,jsp页面会向后台发送一个请求参数relocate,值为当前页码+1;
当我们点击下一页时,relocate的值为当前页码-1;
点击首页时,relocate的值为1,即重定位到第一页;
点击尾页时,relocate的值为总页数,即重定位到最后一页
点击刷新,relocate的值为1,重定位到第一页

当前页面中的数据从开始到结束的编号
首先我们要知道当前页面中第一条数据的编号,我们可以这样来判断:
上一页最后一条数据编号 =( 当前页码 - 1)*每页显示条数
然后我们就可以采用sql的分页语句limit来查询

select * from mytable limit 上一页最后一条数据编号 ,页面容量

因为limit语句中的查询开始数据是从第一个参数+1开始的,所以上述语句可以查询到本页中所有数据

现在开始实现

1、数据库的设计

CREATE TABLE `goods` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT ,
  `name` varchar(50) DEFAULT NULL ,
  `created` datetime DEFAULT NULL ,
  `updated` datetime DEFAULT NULL ,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1183 DEFAULT CHARSET=utf8'

一个商品表,主键为id,有属性name、created和updated这三个属性

2、pojo类

    private Long id;
	private String name;
	private Date created;
	private Date updated;

名为Goods,省去getter和setter方法

3、dao层

//水平有限,就不使用接口+代理了,直接类走起
public class pagDao {
    //第一个方法,统计数据总数
	public Integer getCount() throws SQLException {
		Integer all = 0;
		Connection conn = DBUtils.getConnection();
		String sql = "select count(*) from goods";
		PreparedStatement pstmt = null;
		try {
			pstmt = (PreparedStatement) conn.prepareStatement(sql);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next()) {
				all = rs.getInt(1);
			}
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			pstmt.close();
			conn.close();
		}
		return all;
	}
    //第二个方法,统计需要查询的数据,需要传入两个参数:上一页最后一条数据的编号和页面容量
    //返回一个List类型的数据,里面存的是需要展示的数据
	public List<Goods> getLimit(Integer startNum,Integer endNum) throws SQLException {
		Connection conn = DBUtils.getConnection();
		String sql = "select * from goods limit ?,?";
		PreparedStatement pstmt = null;
		List<Goods> limit = new ArrayList();
		try {
			pstmt = (PreparedStatement) conn.prepareStatement(sql);
			pstmt.setInt(1, startNum);
			pstmt.setInt(2, endNum);
			ResultSet rs = pstmt.executeQuery();
			while (rs.next()) {
				Goods g = new Goods();
				g.setName(rs.getString("name"));
				g.setId(rs.getLong("id"));
				g.setCreated(rs.getDate("created"));
				g.setUpdated(rs.getDate("updated"));
				limit.add(g);
			}
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			pstmt.close();
			conn.close();
		}
		return limit;
	}
}

4、service层

public interface pagService {
    //设置页面容量
	public Integer setCapacity();
	//设置总条数
	public Integer setCount() throws SQLException;
	//设置总页数
	public Integer setWholePage() throws SQLException;
	//设置需要展示的数据
	public List<Goods> setList(Integer startNum,Integer endNum) throws SQLException;
}

5、serviceImpl层

public class pagServiceImpl implements pagService{
	//注入dao对象
	pagDao pagedao = new pagDao();
	//count为总数据,wholePage为总页数,capacity为页面容量
	//startNum和endNum为分页查询参数,startNum为上一页最后一条数据编号,endNum为页面容量
	Integer count,wholePage,startNum,endNum,capacity=5;
	public List<Goods> setList(Integer startNum,Integer endNum) throws SQLException {
		List<Goods> list = pagedao.getLimit(startNum,endNum);
		return list;
	}
	
	public Integer setCount() throws SQLException {
		count = pagedao.getCount();
		return count;
	}
	
	public Integer setCapacity() {
		return capacity;
	}
	
	public Integer setWholePage() throws SQLException {
		count = setCount();
		capacity = setCapacity();
		wholePage = count/capacity;
		int judge = count%capacity;
		if(judge!=0)
			wholePage++;
		return wholePage;
	}	
}

6、controller层

public class PageController extends HttpServlet {

private static final long serialVersionUID = 1L;
//注入service对象
pagService pagservice = new pagServiceImpl();
//List为要展示的数据,pageNow为当前页码
List<Goods> list;
Integer count, wholePage, startNum, pageNow, capacity;

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取前台表示跳转的参数
	String relocate = req.getParameter("relocate");
	try {
	    //统计总条数
		count = pagservice.setCount();
		//统计页面容量
		capacity = pagservice.setCapacity();
		//统计总页数
		wholePage = pagservice.setWholePage();
		//若第一次访问页面,则前台来的参数relocate为空
		if (relocate == null) {
		//第一次访问默认当前页码为1
			pageNow = startNum = 1;
		} else {
		//不是第一次访问
			startNum = Integer.parseInt(relocate);
			//若在第一页点击了“上一页”,默认返回本页
			if (startNum == 0)
				startNum = 1;
			//若在最后一页点击了“下一页”,默认返回本页
			if (startNum - 1 == wholePage)
				startNum = wholePage;
		//不是第一次访问,则当前页码为前台传过来的参数relocate,代表当前页码
			pageNow = startNum;
		}
		//查询要展示的数据
		list = pagservice.setList((startNum - 1) * capacity, capacity);
		//设置域对象
		req.setAttribute("LIST", list);
		req.setAttribute("COUNT", count);
		req.setAttribute("PAGENOW", pageNow);
		req.setAttribute("CAPACITY", capacity);
		req.setAttribute("WHOLEPAGE", wholePage);
	} catch (SQLException e) {
		e.printStackTrace();
	}
	//请求重定向
	req.getRequestDispatcher("/index01.jsp").forward(req, resp);
}

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	doGet(req, resp);
}

}

7、jsp页面的设计

<body>
    <table width="500" border="1px" id="idData">
		<tr>
			<td>编号</td>
			<td>名称</td>
			<td>创建时间</td>
			<td>更新时间</td>
		</tr>
		<c:forEach items="${LIST}" var="g">
		<tr>
		    <td>${g.getId()}</td>
			<td>${g.getName()}</td>
			<td>${g.getUpdated()}</td>
			<td>${g.getCreated()}</td>
		</tr>
        </c:forEach>
	</table>
	<br />
	<a href="${request.pageContext.ContextPath}/pagination/controller?relocate=1">首页</a>
	<a href="${request.pageContext.ContextPath}/pagination/controller?relocate=${PAGENOW-1}">上一页</a>
	<a href="${request.pageContext.ContextPath}/pagination/controller?relocate=${PAGENOW+1}">下一页</a>
	<a href="${request.pageContext.ContextPath}/pagination/controller?relocate=${WHOLEPAGE}">尾页</a>
	<a href="${request.pageContext.ContextPath}/pagination/controller?relocate=1">刷新</a>
	</br>
	总共${WHOLEPAGE}页, ${COUNT}条数据&nbsp; &nbsp; &nbsp;&nbsp;
	当前第${PAGENOW}页, 每页显示${CAPACITY}条
</body>

分页首先到这里,下次做个优化,用JS和Ajax来写,我想因该会简单很多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值