java实现数据分页展示

分页

在开发中我们经常需要从后端查询数据到前端页面展示,当我们的数据很多的时候就可以使用到分页技术,会使得我们的数据显示更加美观合理。

分页分类

有两种分页方式:

  1. “假分页”
    其实就是采用前端技术对数据进行分页。当前端页面请求后台时将所有符合条件数据全部查询出来响应给前端,在前端通过一些技术对查询出来的数据进行分页。这种方式在数据量较小时效率还行,但是如果当数据量很大时就比较力不从心了,响应会比较慢
  2. “真分页”
    当前端请求后台查询数据时,后台根据前端传入的分页依据使用SQL的分页查询查询对应条数的数据。这种方式就大大的减少了数据量。

分页实现

当前分页实现的项目环境是Spring+SpringMVC
在这里插入图片描述
为了便于操作并且不仅仅在一个项目中能够使用分页技术,创建一个分页对象,其中包含的字段如图中所示。
其中,我们需要从前端传入的数据有当前页(如果想随时更改每一页的数据显示数量就还要传入每页要显示的数据条数)。其他的数据:
首页:恒为1;
总页数:根据通过dao层操作数据库查询而得到的总数据量/每页显示数据量得到

lastPage=totalData%pageSize==0?totalData/pageSize:totalData/pageSize+1

尾页:等于总页数
上一页:这里需要判断当前页是否<=1如果满足则上一页为1,否则上一页就等于当前页-1

prePage=currentPage<=1?1:currentPage-1

下一页:判断当前页是否>=总页数,如果满足则下一页=总页数,否则下一页=当前页-1

nextPage=currentPage>=lastPage?totalPage:currentPage+1

大体流程

前端访问页面发送请求->被SpringMVC核心DispatcherServlet拦截并且匹配到对应的Controller处理器中进行处理->在处理器中获取到当前页(如果是第一次访问则置当前页为1)->通过Service访问对应的Dao层操作方法->在dao方法中根据传入的当前页首先操作数据库查询出总数据数并封装到对象中->我是在分页实体类的有参构造方法中进行的其他元素的值的计算->分页对象数据封装完成之后就可以进行分页查询了->使用SQL的分页查询语句查询出符合条件的数据(SELECT * FROM … LIMIT 起始,每页数据量);其中的起始位置是可以通过 (当前页-1)*每页的数据量算出的->将查询出的数据list封装到分页对象中传递回Controller->响应给前端,前端使用jstl+el解析展示

实现

定义分页对象实体类:

import java.util.List;

public class PageList<T> {
	private Integer currentpage = 1; // 当前页,初始值也为第一页
	private Integer firstPage = 1;// 首页为第一页
	private Integer prePage; // 上一页
	private Integer nextPage; // 下一页
	private Integer lastPage; // 最后一页
	private Integer totalPage; // 总页数
	private Integer totalData; // 总数据
	private Integer pageSize; // 
	private List<T> list; // list集合用来装查出的数据

	public PageList() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public String toString() {
		return "PageList [currentpage=" + currentpage + ", firstPage=" + firstPage + ", prePage=" + prePage
				+ ", nextPage=" + nextPage + ", lastPage=" + lastPage + ", totalPage=" + totalPage + ", totalData="
				+ totalData + ", pageSize=" + pageSize + ", list=" + list + "]";
	}

	public Integer getCurrentpage() {
		return currentpage;
	}

	public void setCurrentpage(Integer currentpage) {
		this.currentpage = currentpage;
	}

	public Integer getFirstPage() {
		return firstPage;
	}

	public void setFirstPage(Integer firstPage) {
		this.firstPage = firstPage;
	}

	public Integer getPrePage() {
		return prePage;
	}

	public void setPrePage(Integer prePage) {
		this.prePage = prePage;
	}

	public Integer getNextPage() {
		return nextPage;
	}

	public void setNextPage(Integer nextPage) {
		this.nextPage = nextPage;
	}

	public Integer getLastPage() {
		return lastPage;
	}

	public void setLastPage(Integer lastPage) {
		this.lastPage = lastPage;
	}

	public Integer getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(Integer totalPage) {
		this.totalPage = totalPage;
	}

	public Integer getTotalData() {
		return totalData;
	}

	public void setTotalData(Integer totalData) {
		this.totalData = totalData;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}

	public PageList(Integer currentpage, Integer totalData, Integer pageSize) {
		this.currentpage = currentpage;
		this.totalData = totalData;
		this.pageSize = pageSize;
		
		/**
		 * 为页面中的尾页、上一页、下一页、总页数赋值
		 */
		// 总页数:总数据/每页数据 。 如果除不尽则向上取整
		this.totalPage = this.totalData % this.pageSize == 0 ? this.totalData / this.pageSize
				: this.totalData / this.pageSize + 1;
		//尾页:等于总页数
		this.lastPage = this.totalPage;
		// 上一页:如果传入当前页页码小于等于1则直接赋值为1
		this.prePage = this.currentpage <= 1 ? 1 : this.currentpage - 1;

		// 下一页:如果传入当前页页码大于等于总页数则赋值为总页数
		this.nextPage = this.currentpage >= this.totalPage ? this.totalPage : this.currentpage + 1;
	}

}

Controller处理实现:

@Controller
@RequestMapping("/system")
public class CMSController {
	
	@Autowired
	private ImageServiceImpl servic;
	@RequestMapping("/main")
	public String main(Integer currentPage, Integer pageSize, HttpSession session) {
		
		if (currentPage == null) {
			currentPage = 1;
		}
		if(pageSize == null) {
			pageSize = 5;
		}
		
		
		PageList<Images> list = servic.queryAll(currentPage,pageSize);
		
		session.setAttribute("page_list", list);
		//在SpringMVC中配置了视图解析器,所以只用返回关键字,完整路径会在视图解析器中自动拼接
		return "main";
	}
	}

视图解析器:

<!-- 配置视图解析器
		可以帮助简化书写繁琐路径的步骤
		自动为我们返回的路径添加前缀后后缀
	 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	 	<property name="prefix" value="/WEB-INF/system/" />
	 	<property name="suffix" value=".jsp" />
	</bean>

Service方法:

@Service
public class ImageServiceImpl implements IImageService {
	@Autowired
	private ImageDaoImpl dao;
	@Override
	public PageList queryAll(Integer currentPage, Integer pageSize) {
		return dao.queryAll(currentPage,pageSize);
	}

}

Dao方法:

@Repository
public class ImageDaoImpl implements IImageDao {

	@Autowired
	private JdbcTemplate jt;   //在Spring中自动注入了连接池对象,可以操作数据库
	@Override
	public PageList queryAll(Integer currentPage, Integer pageSize) {
		/**
		 * 要根据传入的当前页计算出上一页、下一页
		 * 	在这里还要计算出数据总条数,和数据总页数
		 */
		//先查询出总数据条数
		String sql = "SELECT COUNT(imgid) FROM images";
		Integer totalData = jt.queryForObject(sql, Integer.class);
		//封装到pageList对象中
		PageList pageList = new PageList(currentPage,totalData, pageSize);
		
		//查询分页数据
		sql = "SELECT * FROM images LIMIT ?, ?";
		//起始位置= (当前页-1)*每页条数
		List<Images> list = jt.query(sql, new BeanPropertyRowMapper(Images.class), (currentPage-1)*pageList.getPageSize(), pageList.getPageSize());
		
		pageList.setList(list);
		
		return pageList;
	}

}

Spring中为jt对象注入值:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
	<!-- 查找当前src下查找jdbc.properties文件 -->
	<context:property-placeholder
		location="classpath:config/jdbc.properties" />

	<bean id="ds"
		class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName"
			value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
	<!-- 创建JdbcTemplate对象用于jdbc操作 -->
	<bean id ="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg name="dataSource" ref="ds"></constructor-arg>
	</bean>
	
	<!-- 扫描所有的包,扫描多个包可以使用逗号分隔 
		Spring负责管理service和dao
	-->
	<context:component-scan base-package="cn.xer.dao.impl, cn.xer.service.impl" />
	
</beans>

到这里,后端的操作基本就完成了,热腾腾的分页对象已放入session,随时可以食用。
前端获取:

<c:forEach items="${sessionScope.page_list.list}" var="main">
				<input type="hidden" id="img_list" value="${sessionScope.img_list }" />
				<tr>
					<input type="hidden" class="id" value="${main.imgid }" />
					<th name="id">${main.imgid }</th>
					<th name="img"><img alt="" src="/upload/${main.storename}"
						style="width: 100px;"></th>
					<th name="storepath">${main.storepath }</th>
					<th name="storename">${main.storename }</th>
					<th name="intro">${main.intro }</th>

					<!-- 判断是否已启用 -->
					<c:choose>

						<c:when test="${main.isenabled == true }">
							<th><span class="glyphicon glyphicon-ok" aria-hidden="true"></span></th>
						</c:when>
						<c:otherwise>
							<th><span class="glyphicon glyphicon-remove"
								aria-hidden="true"></span></th>
						</c:otherwise>
					</c:choose>

					<th name="date">${main.date }</th>

					<th><button class="btn-default tableA edit" style="border-radius:8px;">
							<span class="glyphicon glyphicon-pencil" aria-hidden="true">修改</span>
						</button> <a href="" class="btn-default tableA"><span
							class="glyphicon glyphicon-trash" aria-hidden="true">删除</span></a></th>
				</tr>
				</c:forEach>
		</table>
		<nav class="navbar-right">
			<ul class="pagination" id="paging">
				<li><span>当前第${sessionScope.page_list.currentpage }页</span></li>
				<li><a
					href="${pageContext.request.contextPath}/system/main?currentPage=1">
						<span aria-hidden="true">首页</span>
				</a></li>
				<li><a
					href="${pageContext.request.contextPath}/system/main?currentPage=${sessionScope.page_list.prePage }"
					aria-label="上一页"> <span aria-hidden="true">上一页</span>
				</a></li>
				<li></li>
				<li><a
					href="${pageContext.request.contextPath}/system/main?currentPage=${sessionScope.page_list.nextPage }"
					aria-label="下一页"> <span aria-hidden="true">下一页</span>
				</a></li>
				<li><a
					href="${pageContext.request.contextPath}/system/main?currentPage=${sessionScope.page_list.lastPage }"
					aria-label="尾页"> <span aria-hidden="true">尾页</span>
				</a></li>
				<li><span>总页数:共${sessionScope.page_list.totalPage }页</span>
					<span>总数据:共${sessionScope.page_list.totalData }条</span></li>
					<li><span>每页显示:
				<select name="pageSize" id="select">
					<option value="${sessionScope.page_list.pageSize }">${sessionScope.page_list.pageSize }</option>
					<option value="5">5</option>
					<option value="8">8</option>
					<option value="10">10</option>
				</select>
				条</span></li>
			</ul>
		</nav>

在需要展示的地方食用jstl+el就可以获取到数据了。
当然还有其他方式能过拿到数据,例如,使用ajax请求后台,在Controller中直接返回一个分页数据对象的json数据,在前端解析使用即可。具体实现就不展示了。

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值