【JavaWeb】书城项目(222-256)
创始人
2025-06-01 02:45:48

222.书城项目-第三阶段:修改所有html页面为jsp页面

改成jsp页面之后,方便回显登录和注册失败之后的错误信息

页面 jsp 动态化
1、在 每个html 页面顶行添加 page 指令。
2、修改文件后缀名为:.jsp
3、地址修改之后无法使用,使用 IDEA 搜索替换.html 为.jsp(快捷键:Ctrl+Shift+R)

在这里插入图片描述

223.书城项目-第三阶段:抽取所有jsp页面中公共内容

新建login_success_menu.jsp文件,抽取公共的部分

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
欢迎韩总光临尚硅谷书城我的订单注销  返回

新建head.jsp,抽取引入的类库等头信息

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%String basePath = request.getScheme()+ "://"+ request.getServerName()+ ":"+ request.getServerPort()+ request.getContextPath()+ "/";
%>
">


新建footer.jsp抽取页脚

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
尚硅谷书城.Copyright ©2015

新建manager_menu.jsp抽取菜单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

使用include可以引入抽取的公共部分

<%--静态包含,登录 成功之后的菜单 --%><%@ include file="/pages/common/login_success_menu.jsp"%>

224.书城项目-动态的base标签值

head.jsp文件解决用户每次访问都是localhost地址

方法作用
request.getScheme()协议
request.getServerName()服务器IP,动态获取每次请求的IP
request.getServerPort()端口号
request.getContextPath()工程路径
<%@ page contentType="text/html;charset=UTF-8" language="java" %><%String basePath = request.getScheme()+ "://"+ request.getServerName()+ ":"+ request.getServerPort()+ request.getContextPath()+ "/";
%>
">


225.书城项目-表单提交失败的错误回显

在这里插入图片描述

以登录回显为示例:
1、Servlet 程序端需要添加回显信息到 Request 域中,提示的信息msg,回显的信息username
2、设置登录失败跳回的页面
在这里插入图片描述

jsp 页面,需要输出回显信息
1、如果等于null,提示请输入用户名密码
2、如果不等于null,提示错误信息
3、在用户名标签的value中判断返回的username
在这里插入图片描述

226.书城项目-代码优化:合并LoginServlet和RegistServlet程序为UserServlet程序

在实际的项目开发中,一个模块,一般只使用一个 Servlet 程序。
将登录和注册Servlet合并成为UserServlet
在这里插入图片描述

UserServlet

package com.atguigu.web;import com.atguigu.pojo.User;
import com.atguigu.service.UserService;
import com.atguigu.service.impl.UserServiceImpl;
import com.atguigu.utils.WebUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class UserServlet extends BaseServlet {private UserService userService = new UserServiceImpl();/*** 处理登录的功能** @param req* @param resp* @throws ServletException* @throws IOException*/protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//  1、获取请求的参数String username = req.getParameter("username");String password = req.getParameter("password");// 调用 userService.login()登录处理业务User loginUser = userService.login(new User(null, username, password, null));// 如果等于null,说明登录 失败!if (loginUser == null) {// 把错误信息,和回显的表单项信息,保存到Request域中req.setAttribute("msg", "用户或密码错误!");req.setAttribute("username", username);//   跳回登录页面req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);} else {// 登录 成功//跳到成功页面login_success.htmlreq.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp);}}/*** 处理注册的功能** @param req* @param resp* @throws ServletException* @throws IOException*/protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//  1、获取请求的参数String username = req.getParameter("username");String password = req.getParameter("password");String email = req.getParameter("email");String code = req.getParameter("code");User user = WebUtils.copyParamToBean(req.getParameterMap(), new User());//        2、检查 验证码是否正确  === 写死,要求验证码为:abcdeif ("abcde".equalsIgnoreCase(code)) {
//        3、检查 用户名是否可用if (userService.existsUsername(username)) {System.out.println("用户名[" + username + "]已存在!");// 把回显信息,保存到Request域中req.setAttribute("msg", "用户名已存在!!");req.setAttribute("username", username);req.setAttribute("email", email);//        跳回注册页面req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);} else {//      可用
//                调用Sservice保存到数据库userService.registUser(new User(null, username, password, email));
//
//        跳到注册成功页面 regist_success.jspreq.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req, resp);}} else {// 把回显信息,保存到Request域中req.setAttribute("msg", "验证码错误!!");req.setAttribute("username", username);req.setAttribute("email", email);System.out.println("验证码[" + code + "]错误");req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);}}
}

还要给 login.jsp 添加隐藏域和修改请求地址
在这里插入图片描述
给 tegist.jsp 页面添加隐藏域 action,和修改请求地址
blog.csdnimg.cn/f9352bf2055148d683bdbc092117ecce.png)

227.书城项目-代码优化二:使用反射优化大量else if代码

将if else判断改为使用反射调用对应的方法

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String action = req.getParameter("action");try {// 获取action 业务鉴别字符串,获取相应的业务方法反射对象Method method = this.getClass().getDeclaredMethod(action, 		HttpServletRequest.class, HttpServletResponse.class);//	System.out.println(method);// 调用目标业务 方法method.invoke(this, req, resp);} catch (Exception e) { e.printStackTrace();
}

228.书城项目-代码优化三:抽取BaseServlet程序

在这里插入图片描述

其它的Servlet改为继承BaseServlet
在这里插入图片描述

package com.atguigu.web;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;public abstract class BaseServlet extends HttpServlet {protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String action = req.getParameter("action");try {// 获取action业务鉴别字符串,获取相应的业务 方法反射对象Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
//            System.out.println(method);// 调用目标业务 方法method.invoke(this, req, resp);} catch (Exception e) {e.printStackTrace();}}
}

229.书城项目-BeanUtils工具类的使用

BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。

BeanUtils 它不是 Jdk 的类。而是第三方的工具类。所以需要导包。
1、导 入 需 要 的 jar 包 : commons-beanutils-1.8.0.jar commons-logging-1.1.1.jar
2、编写 WebUtils 工具类使用:

package com.atguigu.utils;import org.apache.commons.beanutils.BeanUtils;
import java.util.Map;public class WebUtils {/*** 把Map中的值注入到对应的JavaBean属性中。* @param value* @param bean*/public static  T copyParamToBean( Map value , T bean ){try {System.out.println("注入之前:" + bean);/*** 把所有请求的参数都注入到user对象中*/BeanUtils.populate(bean, value);System.out.println("注入之后:" + bean);} catch (Exception e) {e.printStackTrace();}return bean;}
}

230.书城项目-第四阶段,使用EL表达式实现表单错误回显

以登录为示例:
在这里插入图片描述

231.书城项目-第五阶段,内容介绍

232.书城项目-MVC概念介绍

MVC 全称:Model 模型、 View 视图、 Controller 控制器。

MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 Web 层的代码如何有效分离,单独工作。

View 视图:只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作——JSP/HTML。
Controller 控制器:只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——Servlet。转到某个页面。或者是重定向到某个页面。
Model 模型:将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂任何与数据处理相关的代码——JavaBean/domain/entity/pojo。

MVC 是一种思想
MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用(目的还是为了降低耦合度)

在这里插入图片描述

233.书城项目-创建图书模块的数据库表

create table t_book(`id` int primary key auto_increment,`name` varchar(100),`price` decimal(11,2),`author` varchar(100),`sales` int,`stock` int,`img_path` varchar(200)
);## 插入初始化测试数据
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
values(null , 'java 从入门到放弃' , '国哥' , 80 , 9999 , 9 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53 , 'static/img/default.jpg');insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '赌神' , '龙伍' , 66.5, 125 , 535 , 'static/img/default.jpg');## 查看表内容
select id,name,author,price,sales,stock,img_path from t_book;

234.书城项目-编写图书模块的JavaBean类Book

public class Book { private Integer id; private String name; private String author;private BigDecimal price; private Integer sales; private Integer stock;private String imgPath = "static/img/default.jpg";

235.书城项目-编写图书模块的Dao和测试

JdbcUtils

package com.atguigu.utils;import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;public class JdbcUtils {private static DruidDataSource dataSource;static {try {Properties properties = new Properties();// 读取 jdbc.properties属性配置文件InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");// 从流中加载数据properties.load(inputStream);// 创建 数据库连接 池dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {e.printStackTrace();}}/*** 获取数据库连接池中的连接* @return 如果返回null,说明获取连接失败
有值就是获取连接成功*/public static Connection getConnection(){Connection conn = null;try {conn = dataSource.getConnection();} catch (Exception e) {e.printStackTrace();}return conn;}/*** 关闭连接,放回数据库连接池* @param conn*/public static void close(Connection conn){if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}} }

BaseDao

package com.atguigu.dao.impl;import com.atguigu.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;public abstract class BaseDao {//使用DbUtils操作数据库private QueryRunner queryRunner = new QueryRunner();/*** update() 方法用来执行:Insert\Update\Delete语句** @return 如果返回-1,说明执行失败
返回其他表示影响的行数*/public int update(String sql, Object... args) {Connection connection = JdbcUtils.getConnection();try {return queryRunner.update(connection, sql, args);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.close(connection);}return -1;}/*** 查询返回一个javaBean的sql语句** @param type 返回的对象类型* @param sql 执行的sql语句* @param args sql对应的参数值* @param 返回的类型的泛型* @return*/public T queryForOne(Class type, String sql, Object... args) {Connection con = JdbcUtils.getConnection();try {return queryRunner.query(con, sql, new BeanHandler(type), args);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.close(con);}return null;}/*** 查询返回多个javaBean的sql语句** @param type 返回的对象类型* @param sql 执行的sql语句* @param args sql对应的参数值* @param 返回的类型的泛型* @return*/public List queryForList(Class type, String sql, Object... args) {Connection con = JdbcUtils.getConnection();try {return queryRunner.query(con, sql, new BeanListHandler(type), args);} catch (SQLException e) {e.printStackTrace();} finally {JdbcUtils.close(con);}return null;}/*** 执行返回一行一列的sql语句* @param sql 执行的sql语句* @param args sql对应的参数值* @return*/public Object queryForSingleValue(String sql, Object... args){Connection conn = JdbcUtils.getConnection();try {return queryRunner.query(conn, sql, new ScalarHandler(), args);} catch (Exception e) {e.printStackTrace();} finally {JdbcUtils.close(conn);}return null;} }

BookDao

package com.atguigu.dao;import com.atguigu.pojo.Book;import java.util.List;public interface BookDao {public int addBook(Book book);public int deleteBookById(Integer id);public int updateBook(Book book);public Book queryBookById(Integer id);public List queryBooks();}

BookDaoImpl

package com.atguigu.dao.impl;import com.atguigu.dao.BookDao;
import com.atguigu.pojo.Book;import java.util.List;public class BookDaoImpl extends BaseDao implements BookDao {@Overridepublic int addBook(Book book) {String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`) values(?,?,?,?,?,?)";return update(sql, book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.getImgPath());}@Overridepublic int deleteBookById(Integer id) {String sql = "delete from t_book where id = ?";return update(sql, id);}@Overridepublic int updateBook(Book book) {String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=? where id = ?";return update(sql,book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.getImgPath(),book.getId());}@Overridepublic Book queryBookById(Integer id) {String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath from t_book where id = ?";return queryForOne(Book.class, sql,id);}@Overridepublic List queryBooks() {String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath from t_book";return queryForList(Book.class, sql);}
}

BookDao 的测试

package com.atguigu.test;import com.atguigu.dao.BookDao;
import com.atguigu.dao.impl.BookDaoImpl;
import com.atguigu.pojo.Book;
import org.junit.Test;import java.math.BigDecimal;import static org.junit.Assert.*;public class BookDaoTest {private BookDao bookDao = new BookDaoImpl();@Testpublic void addBook() {bookDao.addBook(new Book(null,"国哥为什么这么帅!", "191125", new BigDecimal(9999),1100000,0,null));}@Testpublic void deleteBookById() {bookDao.deleteBookById(21);}@Testpublic void updateBook() {bookDao.updateBook(new Book(21,"大家都可以这么帅!", "国哥", new BigDecimal(9999),1100000,0,null));}@Testpublic void queryBookById() {System.out.println( bookDao.queryBookById(21) );}@Testpublic void queryBooks() {for (Book queryBook : bookDao.queryBooks()) {System.out.println(queryBook);}}
}

236.书城项目- 编写图书模块的Service和测试

BookService

package com.atguigu.service;import com.atguigu.pojo.Book;
import java.util.List;public interface BookService {public void addBook(Book book);public void deleteBookById(Integer id);public void updateBook(Book book);public Book queryBookById(Integer id);public List queryBooks();
}

BookServiceImpl

package com.atguigu.service.impl;import com.atguigu.dao.BookDao;
import com.atguigu.dao.impl.BookDaoImpl;
import com.atguigu.pojo.Book;
import com.atguigu.service.BookService;import java.util.List;public class BookServiceImpl implements BookService {private BookDao bookDao = new BookDaoImpl();@Overridepublic void addBook(Book book) {bookDao.addBook(book);}@Overridepublic void deleteBookById(Integer id) {bookDao.deleteBookById(id);}@Overridepublic void updateBook(Book book) {bookDao.updateBook(book);}@Overridepublic Book queryBookById(Integer id) {return bookDao.queryBookById(id);}@Overridepublic List queryBooks() {return bookDao.queryBooks();}
}

BookServiceTest

package com.atguigu.test;import com.atguigu.pojo.Book;
import com.atguigu.service.BookService;
import com.atguigu.service.impl.BookServiceImpl;
import org.junit.Test;import java.math.BigDecimal;import static org.junit.Assert.*;public class BookServiceTest {private BookService bookService = new BookServiceImpl();@Testpublic void addBook() {bookService.addBook(new Book(null,"国哥在手,天下我有!", "1125", new BigDecimal(1000000), 100000000, 0, null));}@Testpublic void deleteBookById() {bookService.deleteBookById(22);}@Testpublic void updateBook() {bookService.updateBook(new Book(22,"社会我国哥,人狠话不多!", "1125", new BigDecimal(999999), 10, 111110, null));}@Testpublic void queryBookById() {System.out.println(bookService.queryBookById(22));}@Testpublic void queryBooks() {for (Book queryBook : bookService.queryBooks()) {System.out.println(queryBook);}}
}

237.书城项目-图书列表功能的实现

在这里插入图片描述
BookServlet 程序中添加 list 方法

protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 通过BookService 查询全部图书List books = bookService.queryBooks();//2 把全部图书保存到Request 域中req.setAttribute("books", books);//3、请求转发到/pages/manager/book_manager.jsp 页面req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req	,resp);
}

修改【图书管理】请求地址
在这里插入图片描述
修改 pages/manager/book_manager.jsp 页面的数据遍历输出

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>




图书管理<%-- 静态包含 base标签、css样式、jQuery文件 --%><%@ include file="/pages/common/head.jsp"%>
图书管理系统<%-- 静态包含 manager管理模块的菜单 --%><%@include file="/pages/common/manager_menu.jsp"%>
名称价格作者销量库存操作
${book.name}${book.price}${book.author}${book.sales}${book.stock}修改删除
添加图书
<%--静态包含页脚内容--%><%@include file="/pages/common/footer.jsp"%>

238.书城项目-前后台的简单介绍

在这里插入图片描述

239.书城项目-添加图书功能实现

在这里插入图片描述
问题说明:表单重复提交:

当用户提交完请求,浏览器会记录下最后一次请求的全部信息。当用户按下功能键 F5,就会发起浏览器记录的最后一次请求。

BookServlet 程序中添加 add 方法
解决方法:将req请求转发,改为resp重定向

    protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//        1、获取请求的参数==封装成为Book对象Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book());
//        2、调用BookService.addBook()保存图书bookService.addBook(book);
//        3、跳到图书列表页面
//                /manager/bookServlet?action=list
//        req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req, resp);resp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=list");}

240.书城项目-删除图书功能的实现

在这里插入图片描述
BookServlet 程序中的 delete 方法

protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1、获取请求的参数id,图书编程int id = WebUtils.parseInt(req.getParameter("id"), 0);
//        2、调用bookService.deleteBookById();删除图书bookService.deleteBookById(id);
//        3、重定向回图书列表管理页面
//                /book/manager/bookServlet?action=listresp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=list");}

给 WebUtils 工具类添加转换 int 类型的工具方法

/*** 将字符串转换成为int类型的数据* @param strInt* @param defaultValue* @return*/public static int parseInt(String strInt,int defaultValue) {try {return Integer.parseInt(strInt);} catch (Exception e) {e.printStackTrace();}return defaultValue;}

修改删除的连接地址:
在这里插入图片描述
给删除添加确认提示操作:

	<%-- 静态包含 base标签、css样式、jQuery文件 --%><%@ include file="/pages/common/head.jsp"%>

241.书城项目-修改图书第一步,回显修改的信息

1、点击修改调用BookServlet.getBook获取图书信息,保存到域中
2、BookServlet.getBook请求转发到bool_edit.jsp页面
3、bool_edit.jsp页面获取域中的信息显示
4、bool_edit.jsp页面修改信息提交给服务器BookServlet.update保存修改
5、BookServlet.update重定向到图书管理页面BookServlet.list
6、页面刷新数据
在这里插入图片描述
更新【修改】的请求地址:
在这里插入图片描述

BookServlet 程序中添加 getBook 方法

	protected void getBook(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 获取请求的参数图书编号int id = WebUtils.parseInt(req.getParameter("id"), 0);//2 调用bookService.queryBookById查询图书Book book = bookService.queryBookById(id);//3 保存到图书到Request域中req.setAttribute("book", book) ;//4 请求转发到。pages/manager/book_edit.jsp页面req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp);}

在 book_edit.jsp 页面中显示修改的数据

	
名称价格作者销量库存操作

242.书城项目-修改图书第二步,提交给服务器保存修改

在 BookServlet 程序中添加 update 方法:

    protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1、获取请求的参数==封装成为Book对象Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book());
//        2、调用BookService.updateBook( book );修改图书bookService.updateBook(book);
//        3、重定向回图书列表管理页面
//        地址:/工程名/manager/bookServlet?action=listresp.sendRedirect(req.getContextPath() + "/manager/bookServlet?action=list");}

解决 book_edit.jsp 页面,即要实现添加,又要实现修改操作。
在这里插入图片描述
book_edit.jsp页面,既要做添加操作,又要做修改操作,而到底是添加还是修改是由一个隐藏域来决定的。如何动态修改隐藏域,让他的值既可以实现添加,又可以实现修改操作。

解决方案一:可以在发请求发起时,附带上当前要操作的值,并注入到隐藏域中
解决方案二:修改有id参数,添加没有id参数。通过判断参数是否有id来确定是添加还是修改操作
解决方案三:可以通过判断Request域中是否包含有修改的图书信息对象,如果没有说明是添加操作,如果有说明是修改操作。

243.书城项目-第五阶段:图书分页的分析

在这里插入图片描述

需要的属性属性名如何获取
pageNo当前页码客户端进行传递
pageTotal总页码总记录数/每页数量
pageTotalCount总记录数sql语句count
pageSize每页显示数量客户端进行传递、页面布局决定
items当前页数据sql语句select limit

244.书城项目-分页模型Page对象的创建

package com.atguigu.pojo;import java.util.List;/*** Page是分页的模型对象* @param  是具体的模块的javaBean类*/
public class Page {public static final Integer PAGE_SIZE = 4;// 当前页码private Integer pageNo;// 总页码private Integer pageTotal;// 当前页显示数量private Integer pageSize = PAGE_SIZE;// 总记录数private Integer pageTotalCount;// 当前页数据private List items;// 分页条的请求地址private String url;    
}

245.书城项目-分页初步实现

BookServlet

/*** 处理分页功能* @param req* @param resp* @throws ServletException* @throws IOException*/protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 获取请求的参数 pageNo 和 pageSizeint pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);//2 调用BookService.page(pageNo,pageSize):Page对象Page page = bookService.page(pageNo,pageSize);page.setUrl("manager/bookServlet?action=page");//3 保存Page对象到Request域中req.setAttribute("page",page);//4 请求转发到pages/manager/book_manager.jsp页面req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);}

BookServiceImpl

	@Overridepublic Page page(int pageNo, int pageSize) {Page page = new Page();// 设置每页显示的数量page.setPageSize(pageSize);// 求总记录数Integer pageTotalCount = bookDao.queryForPageTotalCount();// 设置总记录数page.setPageTotalCount(pageTotalCount);// 求总页码Integer pageTotal = pageTotalCount / pageSize;if (pageTotalCount % pageSize > 0) {pageTotal+=1;}// 设置总页码page.setPageTotal(pageTotal);// 设置当前页码page.setPageNo(pageNo);// 求当前页数据的开始索引int begin = (page.getPageNo() - 1) * pageSize;// 求当前页数据List items = bookDao.queryForPageItems(begin,pageSize);// 设置当前页数据page.setItems(items);return page;}

BookDaoImpl

	@Overridepublic Integer queryForPageTotalCount() {String sql = "select count(*) from t_book";Number count = (Number) queryForSingleValue(sql);return count.intValue();}@Overridepublic List queryForPageItems(int begin, int pageSize) {String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath from t_book limit ?,?";return queryForList(Book.class,sql,begin,pageSize);}

manager_menu.jsp 中【图书管理】请求地址的修改:
在这里插入图片描述
book_manager.jsp 修改:

首页上一页3【${ requestScope.page.pageNo }】5下一页末页共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录到第

246.书城项目-首页、上一页、下一页、末页的实现

在这里插入图片描述

247.书城项目-跳到指定页码功能的实现

到第

Page 对象中的修改:

public void setPageNo(Integer pageNo) {
/* 数据边界的有效检查 */if (pageNo < 1) { pageNo = 1;}if (pageNo > pageTotal) { pageNo = pageTotal;}this.pageNo = pageNo;
}

BookService 中 page 方法的修改:

@Overridepublic Page page(int pageNo, int pageSize) {Page page = new Page();// 设置每页显示的数量page.setPageSize(pageSize);// 求总记录数Integer pageTotalCount = bookDao.queryForPageTotalCount();// 设置总记录数page.setPageTotalCount(pageTotalCount);// 求总页码Integer pageTotal = pageTotalCount / pageSize;if (pageTotalCount % pageSize > 0) {pageTotal+=1;}// 设置总页码page.setPageTotal(pageTotal);// 设置当前页码page.setPageNo(pageNo);// 求当前页数据的开始索引int begin = (page.getPageNo() - 1) * pageSize;// 求当前页数据List items = bookDao.queryForPageItems(begin,pageSize);// 设置当前页数据page.setItems(items);return page;}

248.书城项目-数据有效边境检查

需求:显示 5 个连续的页码,而且当前页码在中间。除了当前页码之外,每个页码都可以点击跳到指定页。
在这里插入图片描述
在这里插入图片描述

249.书城项目-分页条码的输出

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%--分页条的开始--%>
<%--大于首页,才显示--%> 1}">首页上一页<%--页码输出的开始--%><%--情况1:如果总页码小于等于5的情况,页码的范围是:1-总页码--%><%--情况2:总页码大于5的情况--%> 5}"><%--小情况1:当前页码为前面3个:1,2,3的情况,页码范围是:1-5.--%><%--小情况2:当前页码为最后3个,8,9,10,页码范围是:总页码减4 - 总页码--%> requestScope.page.pageTotal-3}"><%--小情况3:4,5,6,7,页码范围是:当前页码减2 - 当前页码加2--%>【${i}】${i}<%--页码输出的结束--%><%-- 如果已经 是最后一页,则不显示下一页,末页 --%>下一页末页共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录到第

250.书城项目-修改分页对原来,添加、删除、修改的影响

以修改图书为示例:

1、在修改的请求地址上追加当前页码参数:
在这里插入图片描述
2、在 book_edit.jsp 页面中使用隐藏域记录下 pageNo 参数
在这里插入图片描述
3、在服务器重定向的时候,获取当前页码追加上进行跳转,update方法
在这里插入图片描述

251.书城项目-前台分页的初步实现

在这里插入图片描述

252.书城项目-分页条的抽取

在 page 对象中添加 url 属性

// 分页条的请求地址	
private String url;	

Servlet 程序的 page 分页方法中设置 url 的分页请求地址
在这里插入图片描述
修改分页条中请求地址为 url 变量输出,并抽取一个单独的 jsp 页面

253.书城项目-价格区间搜索并分页的分析

在这里插入图片描述

254.书城项目-价格区间搜索并分页的功能实现

ClientBookServlet

package com.atguigu.web;import com.atguigu.pojo.Book;
import com.atguigu.pojo.Page;
import com.atguigu.service.BookService;
import com.atguigu.service.impl.BookServiceImpl;
import com.atguigu.utils.WebUtils;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;public class ClientBookServlet extends BaseServlet {private BookService bookService = new BookServiceImpl();/*** 处理分页功能* @param req* @param resp* @throws ServletException* @throws IOException*/protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 获取请求的参数 pageNo 和 pageSizeint pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);//2 调用BookService.page(pageNo,pageSize):Page对象Page page = bookService.page(pageNo,pageSize);page.setUrl("client/bookServlet?action=page");//3 保存Page对象到Request域中req.setAttribute("page",page);//4 请求转发到pages/manager/book_manager.jsp页面req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);}/*** 处理分页功能* @param req* @param resp* @throws ServletException* @throws IOException*/protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1 获取请求的参数 pageNo 和 pageSizeint pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);int min = WebUtils.parseInt(req.getParameter("min"), 0);int max = WebUtils.parseInt(req.getParameter("max"), Integer.MAX_VALUE);//2 调用BookService.page(pageNo,pageSize):Page对象Page page = bookService.pageByPrice(pageNo,pageSize,min,max);StringBuilder sb = new StringBuilder("client/bookServlet?action=pageByPrice");// 如果有最小价格的参数,追加到分页条的地址参数中if (req.getParameter("min") != null) {sb.append("&min=").append(req.getParameter("min"));}// 如果有最大价格的参数,追加到分页条的地址参数中if (req.getParameter("max") != null) {sb.append("&max=").append(req.getParameter("max"));}page.setUrl(sb.toString());//3 保存Page对象到Request域中req.setAttribute("page",page);//4 请求转发到pages/manager/book_manager.jsp页面req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);}
}

255.书城项目-搜索价格区间的回显
256.书城项目-解决分页条中不带价格区间的bug

相关内容

热门资讯

【实验报告】实验一 图像的... 实验目的熟悉Matlab图像运算的基础——矩阵运算;熟悉图像矩阵的显示方法࿰...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
大模型落地比趋势更重要,NLP... 全球很多人都开始相信,以ChatGPT为代表的大模型,将带来一场NLP领...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
kuernetes 资源对象分... 文章目录1. pod 状态1.1 容器启动错误类型1.2 ImagePullBackOff 错误1....
STM32实战项目-数码管 程序实现功能: 1、上电后,数码管间隔50ms计数; 2、...
TM1638和TM1639差异... TM1638和TM1639差异说明 ✨本文不涉及具体的单片机代码驱动内容,值针对芯...
Qt+MySql开发笔记:Qt... 若该文为原创文章,转载请注明原文出处 本文章博客地址:https://h...
Java内存模型中的happe... 第29讲 | Java内存模型中的happen-before是什么? Java 语言...
《扬帆优配》算力概念股大爆发,... 3月22日,9股封单金额超亿元,工业富联、鸿博股份、鹏鼎控股分别为3.0...
CF1763D Valid B... CF1763D Valid Bitonic Permutations 题目大意 拱形排列࿰...
SQL语法 DDL、DML、D... 文章目录1 SQL通用语法2 SQL分类3 DDL 数据定义语言3.1 数据库操作3.2 表操作3....
文心一言 VS ChatGPT... 3月16号,百度正式发布了『文心一言』,这是国内公司第一次发布类Chat...
CentOS8提高篇5:磁盘分...        首先需要在虚拟机中模拟添加一块新的硬盘设备,然后进行分区、格式化、挂载等...
Linux防火墙——SNAT、... 目录 NAT 一、SNAT策略及作用 1、概述 SNAT应用环境 SNAT原理 SNAT转换前提条...
部署+使用集群的算力跑CPU密... 我先在开头做一个总结,表达我最终要做的事情和最终环境是如何的,然后我会一...
Uploadifive 批量文... Uploadifive 批量文件上传_uploadifive 多个上传按钮_asing1elife的...
C++入门语法基础 文章目录:1. 什么是C++2. 命名空间2.1 域的概念2.2 命名...
2023年全国DAMA-CDG... DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义...
php实现助记词转TRX,ET... TRX助记词转地址网上都是Java,js或其他语言开发的示例,一个简单的...
【分割数据集操作集锦】毕设记录 1. 按要求将CSV文件转成json文件 有时候一些网络模型的源码会有data.json这样的文件里...
Postman接口测试之断言 如果你看文字部分还是不太理解的话,可以看看这个视频,详细介绍postma...
前端学习第三阶段-第4章 jQ... 4-1 jQuery介绍及常用API导读 01-jQuery入门导读 02-JavaScri...
4、linux初级——Linu... 目录 一、用CRT连接开发板 1、安装CRT调试工具 2、连接开发板 3、开机后ctrl+c...
Urban Radiance ... Urban Radiance Fields:城市辐射场 摘要:这项工作的目标是根据扫描...
天干地支(Java) 题目描述 古代中国使用天干地支来记录当前的年份。 天干一共有十个,分别为:...
SpringBoot雪花ID长... Long类型精度丢失 最近项目中使用雪花ID作为主键,雪花ID是19位Long类型数...
对JSP文件的理解 JSP是java程序。(JSP本质还是一个Servlet) JSP是&#...
【03173】2021年4月高... 一、单向填空题1、大量应用软件开发工具,开始于A、20世纪70年代B、20世纪 80年...
LeetCode5.最长回文子... 目录题目链接题目分析解题思路暴力中心向两边拓展搜索 题目链接 链接 题目分析 简单来说࿰...