JAVA框架-分页展示与查询
今天来练习一个案例,做的是分页展示与查询,以联系刚刚学过的MVC设计模式。
问题的根本原因就在于一次性展示的数据太多,那么解决方案也就是一次性显示一部分数据,这也是分页展示的本质
最后的形式呢,就如图,分页展示我们的foodlist
查询核心sql语句
#如上述显示第一页的第1-3条数据,sql语句为:
select *from food limit 0,3;
#第二页第4-6条数据,sql语句为
select *from food limit 3,3;
#第三页第4-6条数据,sql语句为
select *from food limit 6,3;
最后我们可以总结出规律:
#设当前页码为 p 每页条数为 n
# select *from food limit start,n;
start = (p-1) * n
#即当前页码减去1 乘以每页条数
页面
下面我们就直接放代码啦,让我们从上往下的走:
<%--
Created by IntelliJ IDEA.
User: 17390
Date: 2020/5/13
Time: 16:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Food$</title>
</head>
<body>
<table>
<tr><th>编号</th><th>名称</th><th>单价</th><th>数量</th></tr>
<%-- <tr><td>1</td><td>苹果</td> <td>1</td> <td>200g</td></tr>--%>
<c:forEach items="${foodList}" var="food">
<tr><td>${food.getID()}</td>
<td>${food.getName()}</td>
<td>${food.getPrice()}</td>
<td>${food.getUnit()}</td>
</tr>
</c:forEach>
</table>
<a href="showFood?page=1">首页</a>
<c:if test="${nowPage >1}">
<a href="showFood?page=${nowPage-1}">上一页</a>
</c:if>
<span>${nowPage}/${totalPage}</span>
<c:if test="${nowPage < totalPage}">
<a href="showFood?page=${nowPage+1}">下一页</a>
</c:if>
<a href="showFood?page=${totalPage}">末页</a>
<c:if test="${empty foodList}">
<jsp:forward page="showFood"></jsp:forward>
</c:if>
</body>
</html>
contraller
package controller;
import model.Food;
import service.FoodService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet(name = "ControllerServlet", urlPatterns = "/showFood")
public class ControllerServlet extends HttpServlet {
private FoodService service;
@Override
public void init() throws ServletException {
try {
service = new FoodService();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取页码和每页条数
String pageStr = request.getParameter("page");
String countStr = request.getParameter("count");
//检查有效性
Integer page = 1;
Integer count = 3;
try {
if( pageStr != null && Integer.valueOf(pageStr) >0 ){
page = Integer.valueOf(pageStr);
}
if( countStr != null && Integer.valueOf(countStr) > 0 ){
count = Integer.valueOf(countStr);
}
//当前分页的数据
List<Food> foodList = service.selectFoodByPage( page, count);
//获得总的页数
int totalPage = service.getTotalPage(count);
//将数据放到request中带着jsp
request.setAttribute("foodList",foodList);
request.setAttribute("totalPage",totalPage);
request.setAttribute("nowPage",page);
//转发页面信息
request.getRequestDispatcher("index.jsp").forward(request,response);
}catch (Exception e){
e.printStackTrace();
System.out.println("页码和页数参数无效!!!");
}
}
}
service
因为项目还比较简单,所以service层基本没干什么事情。但是我们为了保持好的习惯,也要添加service层
package service;
import dao.FoodDao;
import model.Food;
import java.util.List;
public class FoodService {
private FoodDao dao;
public FoodService() throws ClassNotFoundException {
dao = new FoodDao();
}
public List<Food> selectFoodByPage(Integer page, Integer count) {
List<Food> list = dao.selectFoodByPage(page,count);
return list;
}
public int getTotalPage(Integer count) {
int totalData = dao.gettotalData(count);
return (totalData%count==0? totalData/count : totalData/count+1 );
}
public static void main(String[] args) {
try {
System.out.println( new FoodService().getTotalPage(3) );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
dao层
这里我们还是使用了封装的jdbc来方便操作
package dao;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DBTool {
public String ip = "127.0.0.1";
public int port = 3306;
public String
user="root",
password="3692512",
charset ="utf8",
dbName="mybase02";
private static boolean DriverLoaded=false;
//使用默认参数链接数据库
public DBTool() throws ClassNotFoundException {
if(DriverLoaded)return;
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("DBTools message:数据库驱动加载成功!");
} catch (ClassNotFoundException e) {
System.out.println("DBTools Error:驱动程序加载失败!");
throw e;
}
DriverLoaded=true;
}
//自定义参数初始化
public DBTool(String ip, int port, String user, String password, String dbName) throws ClassNotFoundException {
this();
this.ip = ip;
this.port = port;
this.user = user;
this.password = password;
this.dbName = dbName;
}
//自定义参数初始化
public DBTool(String user, String password, String dbName) throws ClassNotFoundException {
this();
this.user = user;
this.password = password;
this.dbName = dbName;
}
//获取一个链接
public Connection getConnection() throws SQLException {
String url = String.format("jdbc:mysql://%s:%s/%s?characterEncoding=%s&user=%s&password=%s&useSSL=false",ip,port,dbName,charset,user,password);
try {
return DriverManager.getConnection(url);
} catch (SQLException e) {
System.out.println("DBTools Error 数据库连接失败!");
throw e;
}
}
//执行查询语句
public List<Map<String,Object>> executeQuery(String sql, Object...args) throws SQLException {
ArrayList<Map<String, Object>> res = new ArrayList<>();
ResultSet resultSet = null;
PreparedStatement preparedStatement = null;
Connection connection = null;
try {
connection = getConnection();
preparedStatement = getPreparedStatement(connection, sql, args);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
resultSet.getMetaData().getColumnCount();
HashMap<String, Object> map = new HashMap<>();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount() ; i++) {
map.put(resultSet.getMetaData().getColumnName(i),resultSet.getObject(i));
}
res.add(map);
}
} catch (SQLException e) {
e.printStackTrace();
throw e;
} finally {
if(resultSet != null)
resultSet.close();
if(preparedStatement != null)
preparedStatement.close();
if(connection != null)
connection.close();
}
return res;
}
//sql参数预处理
private PreparedStatement getPreparedStatement(Connection connection, String sql, Object[] args) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
int count = sql.length() - sql.replace("?", "").length();
if(count != args.length){
throw new SQLException("DBTool Error: 参数个数不匹配");
}
for (int i = 0; i < args.length; i++) {
preparedStatement.setObject(i+1,args[i]);
}
return preparedStatement;
}
//执行更新语句 包括delete update insert
public boolean executeUpdate(String sql,Object...args) throws SQLException {
try {
Connection connection = getConnection();
PreparedStatement preparedStatement = getPreparedStatement(connection, sql, args);
int i = preparedStatement.executeUpdate();
if (i>0){return true;}
} catch (SQLException e) {
e.printStackTrace();
throw e;
}
return false;
}
}
这里是我们真正的dao操作
package dao;
import model.Food;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class FoodDao {
private DBTool tool;
public FoodDao() throws ClassNotFoundException {
tool = new DBTool();
}
public List<Food> selectFoodByPage(Integer page, Integer count) {
String sql = "select * from food limit ?,?";
List<Food> list = new ArrayList<>();
try {
List<Map<String, Object>> maps = tool.executeQuery(sql,(page-1)*count,count);
for (Map<String, Object> map: maps) {
Food food = new Food();
food.setID(map.get("id").toString());
food.setName(map.get("name").toString());
food.setPrice(map.get("price").toString());
food.setUnit( map.get("unit").toString());
list.add(food);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
public static void main(String[] args) {
try {
List<Food> foodList = new FoodDao().selectFoodByPage(2, 3);
System.out.println(foodList);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public int gettotalData(Integer count) {
String sql = "SELECT * FROM food";
List<Map<String, Object>> maps = null;
try {
maps = tool.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return maps.size();
}
}
Emmmm.............
挺简单的一个分页展示和查询的练习。但是写了一遍之后对mvc的理解能够更佳深刻。