项目背景:例如京东,淘宝等等web网站项目中,部分信息是需要分页获取的。
所用技术:JSP,SQL语句,Servlet,MVC开发模式(博主有一篇关于MVC开发模式的博客https://blog.csdn.net/my_name_is_zwz/article/details/81054172),HTML,CSS以及Java基础知识中封装等等概念(如果不熟悉这几类技术的小朋友,建议先不要看这篇博客)
接下来先上首页index.jsp中的代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<jsp:forward page="goods.do?method=fenye"></jsp:forward>
<!-- forward动作标签。作用:当前页面执行到forward指令处后转向其他jsp页面执行。这里转到了一个访问资源名叫做goods.do的servlet,并且带去一个名字叫做method,内容等于fenye的参数 -->
接下来是资源名叫做goods.do而名字叫做GoodsServlet的servlet文件代码:
package com.servlet;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dao.GoodsDao;
import com.pojo.Goods;
public class GoodsServlet extends HttpServlet {
private GoodsDao goodsDao = new GoodsDao();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String method = request.getParameter("method");//定义一个字符串,接受index.jsp传来的名字为method的参数
if("fenye".equals(method)){//对参数内容进行判断,如果内容等于fenye,则执行dofenye这个方法
doFenye(request,response);
}
}
private void doFenye(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//page指 :显示哪一页,size指:一页中显示多少数据
int page = 1;//默认page值(如果在index.jsp中没有传来page的值时起作用)
int size = 4;//默认的size值(如果在index.jsp中没有传来size的值时起作用)
String pageString = request.getParameter("page");//接受index.jsp传来的名字为page参数
if (pageString != null) {
page = Integer.parseInt(pageString);//如果用户传了page的值,就用用户所传的
}
String sizeString = request.getParameter("size");//接受index.jsp传来的名字为size参数
if (sizeString != null) {
size = Integer.parseInt(sizeString);
}
if (page < 1) {//如果用户输入的page的值不合法,即小于1时,page=1
page = 1;
}
// 查总条数
int count = goodsDao.getCount();
// 得总页数,以用来下面page是否越界的判断
int pageCount = count % size == 0 ? count / size : count / size + 1;
if (page > pageCount) {
page = pageCount;
}
// 查处商品的集合
List<Goods> list = goodsDao.fenye(page, size);
Map map = new HashMap();//Map是一种把键和值进行映射的容器,每一个元素都包含了一对键和值对象
map.put("page", page);//将page值存入容器
map.put("count", count);
map.put("pageCount", pageCount);
map.put("size", size);
map.put("list", list);
request.setAttribute("map", map);//将map存储在request中,并通过转发将其带到新的jsp页面
request.getRequestDispatcher("show.jsp").forward(request, response);//转发去show.jsp
}
}
在这里先不展示show.jsp的代码,先把工具包com.util中用于查询数据库的所有操作的DButil类(博主有一篇专门讲述Dbutil封装思想的博客https://blog.csdn.net/my_name_is_zwz/article/details/81084009,所以此处不再详细解释)介绍一下:
package com.util;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
public class DButil {
//实例化连接池
public static Vector<Connection> connectionPool = new Vector<Connection>();
//初始化连接池
static {
try {
Class.forName("com.mysql.jdbc.Driver");// 加载驱动
Connection connection = DriverManager.getConnection(
"jdbc:mysql://127.0.0.1:3307/servletdemo", "root", "admin");// 得到连接对象
for (int i = 0; i < 10; i++) {// 利用for循环得到十个连接对象,并且把他们加入到连接池
connectionPool.add(connection);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//取连接
public static Connection getConnection(){
Connection connection = connectionPool.get(0);
connectionPool.remove(0);
return connection;
}
//释放连接
public static void releaseConnection(Connection connection){
connectionPool.add(connection);
}
//增删改
public static void zsg(String sql,Object...objects){
Connection connection = null;
try {
connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if(objects != null){
for(int i=0; i < objects.length; i++){
preparedStatement.setObject( i+1, objects[i]);
}
}
int n = preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
releaseConnection(connection);
}
}
//查询
public static List query(Class c,String sql,Object...objects){
List list = new ArrayList();
Connection connection = getConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if(objects != null){
for(int i = 0;i<objects.length;i++){
preparedStatement.setObject(i+1,objects[i]);
}
}
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
int count = resultSetMetaData.getColumnCount();//得到总列数
Object object = c.newInstance();
while(resultSet.next()){
for(int i = 1; i<=count; i++){
String fieldName = resultSetMetaData.getColumnLabel(i);
Field field = c.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, resultSet.getObject(i));
}
list.add(object);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
releaseConnection(connection);
}
return list;
}
//聚合查询(返回的是表中的所有条数,在MVC的DAO层中SQL语句写的是查询所有条数)
public static int uniqueQuery(String sql,Object...objects){
int count = 0;
Connection connection = null;
try {
connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if(objects != null){
for(int i = 0;i<objects.length;i++){
preparedStatement.setObject(i+1, objects[i]);
}
}
ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();//一开始指向的是第一行的前面,所以要让他下来指向第一行
count = resultSet.getInt(1);//由于SQL语句写的是查询count()
} catch (SQLException e) {
e.printStackTrace();
}finally{
releaseConnection(connection);
}
return count;
}
}
接下来是DAO层中用于操作DButil的GoodsDao类。在servlet中所有调用数据库都是通过dao层,然后在dao层中通过工具包util中的DButil工具类来完成数据库数据的访问:
package com.dao;
import java.util.ArrayList;
import java.util.List;
import com.pojo.Goods;
import com.util.DButil;
public class GoodsDao {
//查询总条数
public static int getCount(){
String sql = "select count(*) from goods";
int count = DButil.uniqueQuery(sql);
return count;
}
//分页查询出来数据信息
public static List<Goods> fenye(int page,int size){
List<Goods> list = new ArrayList<Goods>();
String sql = "select goodsname,goodsphoto from goods limit ?,?";
list = DButil.query(Goods.class, sql, (page-1)*size,size);
return list;
}
}
com.pojo中Goods类的代码:
package com.pojo;
public class Goods {
private String goodsname;
private String goodsphoto;
public String getGoodsname() {
return goodsname;
}
public void setGoodsname(String goodsname) {
this.goodsname = goodsname;
}
public String getGoodsphoto() {
return goodsphoto;
}
public void setGoodsphoto(String goodsphoto) {
this.goodsphoto = goodsphoto;
}
}
show.jsp代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!-- jsp核心标签库 -->
<c:forEach items="${map.list }" var="goods"><!-- 遍历map中的list -->
${goods.goodsname }
<img src="${pageContext.request.contextPath }/image/${goods.goodsphoto}">
</c:forEach>