目录
图书模块
数据库图书表的创建
图书主要有id(图书id)、name(),price(加个)、author(作者)、sales(已售数量)、stock(库存)、img_path(图书的图片)这几个属相,我们创建相应的图书表b_book。创建成功之后随便插入一些数据测试时使用。
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)
);
编写JavaBean
1.创建Book类,属性与数据库图书表中的一致,并提供相应的get、set方法,空参和无参的构造器,tostring方法。
/**
* @author glq
* @create 2020-04-19 17:22
*/
public class Book {
private Integer id;
private String name;
private String author
private BigDecimal price;
private Integer sales;
private Integer stock;
private String img_path = "static/img/default.jpg";
public Book() {
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", sales=" + sales +
", stock=" + stock +
", img_path='" + img_path + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getSales() {
return sales;
}
public void setSales(Integer sales) {
this.sales = sales;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public String getImg_path() {
return img_path;
}
public void setImg_path(String img_path) {
this.img_path = img_path;
}
public Book(Integer id, String name, String author, BigDecimal price, Integer sales, Integer stock, String img_path) {
this.id = id;
this.name = name;
this.author = author;
this.price = price;
this.sales = sales;
this.stock = stock;
this.img_path = img_path;
}
}
2.创建page类,主要有当前页码,总页码,当前页显示的数量、总记录数、当前页数据、页码的请求地址,这几个属性,并提供相应的get、set方法,空参和无参的构造器,tostring方法。
public class Page<T> {
public static final Integer PAGE_SIZE = 4;
// 当前页码
private Integer pageNo;
// 总页码
private Integer pageTotal;
// 当前页显示数量
private Integer pageSize = PAGE_SIZE;
// 总记录数
private Integer pageTotalCount;
// 当前页数据
private List<T> items;
// 分页条的请求地址
private String url;
@Override
public String toString() {
return "Page{" +
"pageNo=" + pageNo +
", pageTotal=" + pageTotal +
", pageSize=" + pageSize +
", pageTotalCount=" + pageTotalCount +
", items=" + items +
", url='" + url + '\'' +
'}';
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
if (pageNo < 1) {
pageNo = 1;
}
if (pageNo > pageTotal) {
pageNo = pageTotal;
}
this.pageNo = pageNo;
}
public Integer getPageTotal() {
return pageTotal;
}
public void setPageTotal(Integer pageTotal) {
this.pageTotal = pageTotal;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getPageTotalCount() {
return pageTotalCount;
}
public void setPageTotalCount(Integer pageTotalCount) {
this.pageTotalCount = pageTotalCount;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Page() {
}
public Page(Integer pageNo, Integer pageTotal, Integer pageSize, Integer pageTotalCount, List<T> items, String url) {
this.pageNo = pageNo;
this.pageTotal = pageTotal;
this.pageSize = pageSize;
this.pageTotalCount = pageTotalCount;
this.items = items;
this.url = url;
}
}
编写BookDao
主要实现添加图书、根据Id删除图书、更新图书、根据id查询图书、查询所有图书、查询图书数量、查询某一页的图书信息,查询某一价格区间的图书数量、查询某一价格区间的图书信息。
**
* @author glq
* @create 2020-04-19 18:03
*/
public class BookDDaoImpl extends BaseDao implements BookDao {
/**
* @Author glq
* @Description //TODO 添加图书
* @Date 18:04 2020/4/19
* @Param [book]
* @return int
**/
@Override
public int addBook(Book book) {
String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`)values(?,?,?,?,?,?)";
int update = update(sql, book.getName(), book.getAuthor(), book.getPrice(), book.getSales(), book.getStock(), book.getImg_path());
return update;
}
/**
* @Author glq
* @Description //TODO 根据Id删除图书
* @Date 18:09 2020/4/19
* @Param [id]
* @return int
**/
@Override
public int deleteBookById(Integer id) {
String sql = "delete from t_book where id = ?";
int update = update(sql, id);
return update;
}
/**
* @Author glq
* @Description //TODO 更新图书
* @Date 18:09 2020/4/19
* @Param [book]
* @return int
**/
@Override
public int updateBook(Book book) {
String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=? where id = ?";
int update = update(sql, book.getName(), book.getAuthor(), book.getPrice(), book.getSales(), book.getStock(), book.getImg_path(), book.getId());
return update;
}
/**
* @Author glq
* @Description //TODO 根据id查询图书
* @Date 18:11 2020/4/19
* @Param [id]
* @return glq.pojo.Book
**/
@Override
public Book queryBookById(Integer id) {
String sql = "select * from t_book where id = ?";
Book book = queryForOne(Book.class, sql, id);
return book;
}
/**
* @Author glq
* @Description //TODO 查询所有图书
* @Date 18:19 2020/4/19
* @Param []
* @return java.util.List<glq.pojo.Book>
**/
@Override
public List<Book> queryBooks() {
String sql = "select * from t_book";
List<Book> books = queryForList(Book.class, sql);
return books;
}
/**
* @Author glq
* @Description //TODO 查询所有图书的数量
* @Date 18:21 2020/4/19
* @Param []
* @return java.lang.Integer
**/
@Override
public Integer queryForPageTotalCount() {
String sql = "select count(*) from t_book";
Number number =(Number) queryForSingleValue(sql);
return number.intValue();
}
/**
* @Author glq
* @Description //TODO 查询某一页的图书
* @Date 18:23 2020/4/19
* @Param [begin, pageSize]
* @return java.util.List<glq.pojo.Book>
**/
@Override
public List<Book> queryForPageItems(int begin, int pageSize) {
String sql = "select * from t_book limit ?,?";
return queryForList(Book.class,sql,begin,pageSize);
}
/**
* @Author glq
* @Description //TODO 查询某一价格区间之间的商品数量
* @Date 18:25 2020/4/19
* @Param [min, max]
* @return java.lang.Integer
**/
@Override
public Integer queryForPageTotalCountByPrice(int min, int max) {
String sql = "select count(*) from t_book where price between ? and ?";
Number number = (Number) queryForSingleValue(sql, min, max);
return number.intValue();
}
/**
* @Author glq
* @Description //TODO 查询某个价格区间某一页的商品
* @Date 18:36 2020/4/19
* @Param [begin, pageSize, min, max]
* @return java.util.List<glq.pojo.Book>
**/
@Override
public List<Book> queryForPageItemsByPrice(int begin, int pageSize, int min, int max) {
String sql = "select * from t_book where price between ? and ? order by price limit ?,?";
// String sql = "select * from t_book where price between ? and ? order by price limit ?,?";
List<Book> books = queryForList(Book.class, sql, min, max, begin, pageSize);
return books;
}
}
编写BookService类
实现增加图书,删除图书,更新图书,根据Id查询图书,分页,根据价格分页这几个功能。
分页:用来返回一个页面的数据,其中pageSize、pageNo是参数提供的,pageTotalCount、items可以通过数据库查询得到,pageTotal可以通过pageTotalCount除pageSize得到(要注意如果有余数页码数要加一)
根据价格分页:与分页相似,只不过pageTotalCount、items所用到的dao中的方法不同。
/**
* @author glq
* @create 2020-04-19 19:28
*/
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDDaoImpl();
@Override
public void addBook(Book book) {
bookDao.addBook(book);
}
@Override
public void deleteBookById(Integer id) {
bookDao.deleteBookById(id);
}
@Override
public void updataBook(Book book) {
bookDao.updateBook(book);
}
@Override
public Book queryBookById(Integer id) {
Book book = bookDao.queryBookById(id);
return book;
}
@Override
public List<Book> queryBooks() {
List<Book> books = bookDao.queryBooks();
return books;
}
@Override
public Page<Book> page(int pageNo, int pageSize) {
Page<Book> bookPage = new Page<>();
bookPage.setPageSize(pageSize);
Integer count = bookDao.queryForPageTotalCount();
bookPage.setPageTotalCount(count);
int pageTotal = count / pageSize;
if(count%pageSize>0){
pageTotal++;
}
bookPage.setPageTotal(pageTotal);
bookPage.setPageNo(pageNo);
int begin = (bookPage.getPageNo()-1)*pageSize;
List<Book> books = bookDao.queryForPageItems(begin, pageSize);
bookPage.setItems(books);
return bookPage;
}
@Override
public Page<Book> pageByPrice(int pageNo, int pageSize, int min, int max) {
Page<Book> bookPage = new Page<>();
bookPage.setPageTotalCount(pageSize);
Integer count = bookDao.queryForPageTotalCountByPrice(min, max);
bookPage.setPageTotal(count);
int pageTotal = count / pageSize;
if(count%pageSize>0){
pageTotal++;
}
bookPage.setPageTotal(pageTotal);
bookPage.setPageNo(pageNo);
int begin = (bookPage.getPageNo()-1)*pageSize;
List<Book> books = bookDao.queryForPageItemsByPrice(begin, pageSize, min, max);
bookPage.setItems(books);
return bookPage;
}
}
编写servlet
这里主要有两个,一个用来后台图书操作的、另外一个用来前台图书信息展示用的。
后台:图书分页显示、添加图书、删除图书、更新图书、查询所有图书这四个功能。
前台:查询某一页的图书、查询某一价格区间的某一页的图书。
后台:
public class BookServlet extends BaseServlet {
private BookServiceImpl bookService = new BookServiceImpl();
/**
* @Author glq
* @Description //TODO 图书分页显示
* @Date 10:40 2020/4/20
* @Param [req, resp]
* @return void
**/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
Page<Book> page = bookService.page(pageNo, pageSize);
page.setUrl("admin/bookServlet?action=page");
req.setAttribute("page",page);
req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
}
/**
* @Author glq
* @Description //TODO 添加图书
* @Date 20:16 2020/4/19
* @Param [req, resp]
* @return void
**/
protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Book book = WebUtils.copyParamToBain(req.getParameterMap(), new Book());
bookService.addBook(book);
String msg = WebUtils.getJson("添加成功");
resp.getWriter().write(msg);
}
/**
* @Author glq
* @Description //TODO 删除图书
* @Date 10:31 2020/4/20
* @Param [req, resp]
* @return void
**/
protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"), 0);
bookService.deleteBookById(id);
resp.sendRedirect(req.getContextPath()+"/admin/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
/**
* @Author glq
* @Description //TODO 更新图书信息
* @Date 10:47 2020/4/20
* @Param [req, resp]
* @return void
**/
protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Book book = WebUtils.copyParamToBain(req.getParameterMap(),new Book());
bookService.updataBook(book);
// resp.sendRedirect(req.getContextPath() + "/admin/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
String msg = WebUtils.getJson("修改成功");
req.setAttribute("pageNo",req.getParameter("pageNo"));
resp.getWriter().write(msg);
// resp.sendRedirect(req.getContextPath() + "/admin/bookServlet?action=page&pageNo=" + req.getParameter("pageNo"));
}
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);
}
protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1 通过BookService查询全部图书
List<Book> 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);
}
}
前台:
/**
* @author glq
* @create 2020-04-20 12:37
*/
public class ClientBookServlet extends BaseServlet {
private BookServiceImpl bookService = new BookServiceImpl();
/**
* @Author glq
* @Description //TODO 图书分页显示
* @Date 10:40 2020/4/20
* @Param [req, resp]
* @return void
**/
protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int pageNo = WebUtils.parseInt(req.getParameter("pageNo"), 1);
int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE);
Page<Book> page = bookService.page(pageNo, pageSize);
page.setUrl("client/bookServlet?action=page");
req.setAttribute("page",page);
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
/**
* @Author glq
* @Description //TODO 根据价格区间分页
* @Date 16:47 2020/4/20
* @Param [req, resp]
* @return void
**/
protected void pageByPrice(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int 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);
Page<Book> bookPage = 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"));
}
bookPage.setUrl(sb.toString());
req.setAttribute("page",bookPage);
req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp);
}
}
修改页面
1.前台和后台的图书信息展示都需要分页显示,将分页条抽取出来。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/4/20
Time: 11:03
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div id="page_nav">
<c:if test="${requestScope.page.pageNo >1}">
<a href="${requestScope.page.url}&pageNo=1">首页</a>
<<a href="${requestScope.page.url}&pageNo=${requestScope.page.pageNo-1}">上一页</a>
</c:if>
<c:choose>
<c:when test="${requestScope.page.pageTotal<=5}">
<c:set var="begin" value="1"></c:set>
<c:set var="end" value="${requestScope.page.pageTotal}"></c:set>
</c:when>
<c:when test="${requestScope.page.pageTotal > 5}">
<c:choose>
<%--小情况1:当前页码为前面3个:1,2,3的情况,页码范围是:1-5.--%>
<c:when test="${requestScope.page.pageNo <= 3}">
<c:set var="begin" value="1"/>
<c:set var="end" value="5"/>
</c:when>
<%--小情况2:当前页码为最后3个,8,9,10,页码范围是:总页码减4 - 总页码--%>
<c:when test="${requestScope.page.pageNo > requestScope.page.pageTotal-3}">
<c:set var="begin" value="${requestScope.page.pageTotal-4}"/>
<c:set var="end" value="${requestScope.page.pageTotal}"/>
</c:when>
<%--小情况3:4,5,6,7,页码范围是:当前页码减2 - 当前页码加2--%>
<c:otherwise>
<c:set var="begin" value="${requestScope.page.pageNo-2}"/>
<c:set var="end" value="${requestScope.page.pageNo+2}"/>
</c:otherwise>
</c:choose>
</c:when>
</c:choose>
<c:forEach begin="${begin}" end="${end}" var="i">
<c:if test="${i == requestScope.page.pageNo}">
【${i}】
</c:if>
<c:if test="${i != requestScope.page.pageNo}">
<a href="${ requestScope.page.url }&pageNo=${i}">${i}</a>
</c:if>
</c:forEach>
<c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}">
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageNo+1}">下一页</a>
<a href="${ requestScope.page.url }&pageNo=${requestScope.page.pageTotal}">末页</a>
</c:if>
共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录
到第<input value="${param.pageNo}" name="pn" id="pn_input"/>页
<input id="searchPageBtn" type="button" value="确定">
<script type="text/javascript">
$(function () {
// 跳到指定的页码
$("#searchPageBtn").click(function () {
var pageNo = $("#pn_input").val();
<%--var pageTotal = ${requestScope.page.pageTotal};--%>
<%--alert(pageTotal);--%>
// javaScript语言中提供了一个location地址栏对象
// 它有一个属性叫href.它可以获取浏览器地址栏中的地址
// href属性可读,可写
location.href = "${pageScope.basePath}${ requestScope.page.url }&pageNo=" + pageNo;
});
});
</script>
</div>
2.修改前台的显示:index.jsp中直接一个jsp的请求转发,转发到ClientBookServlet中,调用page方法.,然后跳转到client/index.jsp中,在jsp中遍历显示图书信息。
<%--
Created by IntelliJ IDEA.
User: Administrator
Date: 2020/4/18
Time: 21:14
To change this template use File | Settings | File Templates.
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>书城首页</title>
<%@ include file="/pages/common/head.jsp"%>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.gif" >
<span class="wel_word">网上书城</span>
<div>
<c:if test="${empty sessionScope.user}">
<a href="pages/user/login.jsp">登录</a> |
<a href="pages/user/regist.jsp">注册</a>
</c:if>
<c:if test="${not empty sessionScope.user}">
<span>欢迎<span class="um_span">${sessionScope.user.username}</span>光临尚硅谷书城</span>
<a href="pages/order/order.jsp">我的订单</a>
<a href="userServlet?action=logout">注销</a>
</c:if>
<a href="pages/cart/cart.jsp">购物车</a>
<a href="pages/manager/manager.jsp">后台管理</a>
</div>
</div>
<div id="main">
<div id="book">
<div class="book_cond">
<form action="client/bookServlet" method="get">
<input type="hidden" name="action" value="pageByPrice">
价格:<input id="min" type="text" name="min" value=""> 元 -
<input id="max" type="text" name="max" value=""> 元
<input type="submit" value="查询" />
</form>
</div>
<div style="text-align: center">
<span>您的购物车中有3件商品</span>
<div>
您刚刚将<span style="color: red">时间简史</span>加入到了购物车中
</div>
</div>
<c:forEach items="${requestScope.page.items}" var="book">
<div class="b_list">
<div class="img_div">
<img class="book_img" alt="" src="static/img/default.jpg" />
</div>
<div class="book_info">
<div class="book_name">
<span class="sp1">书名:</span>
<span class="sp2">${book.name}</span>
</div>
<div class="book_author">
<span class="sp1">作者:</span>
<span class="sp2">${book.author}</span>
</div>
<div class="book_price">
<span class="sp1">价格:</span>
<span class="sp2">¥${book.price}</span>
</div>
<div class="book_sales">
<span class="sp1">销量:</span>
<span class="sp2">${book.sales}</span>
</div>
<div class="book_amount">
<span class="sp1">库存:</span>
<span class="sp2">${book.stock}</span>
</div>
<div class="book_add">
<button>加入购物车</button>
</div>
</div>
</div>
</c:forEach>
<%--</div>--%>
</div>
<%@ include file="/pages/common/page_nav.jsp"%>
</div>
<%@ include file="/pages/common/foot.jsp"%>
</body>
</html>
3.修改后台的页面。实现图书的增删改,其中图书的增加和删除用的是同一个页面,这里只需要获取图书,然后写到域中,然后在页面中判断域中有没有数据,若是有则证明是修改,若是没有则证明是添加。
book_manager.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">
$(function () {
$("a.deleteClass").click(function () {
return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】?");
});
});
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="../../static/img/logo.gif" >
<span class="wel_word">图书管理系统</span>
<%@ include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<c:forEach items="${requestScope.page.items}" var="book">
<tr>
<td>${book.name}</td>
<td>${book.price}</td>
<td>${book.author}</td>
<td>${book.sales}</td>
<td>${book.stock}</td>
<td><a href="admin/bookServlet?action=getBook&id=${book.id}&pageNo=${requestScope.page.pageNo}">修改</a></td>
<td><a href="admin/bookServlet?action=delete&id=${book.id}&pageNo=${requestScope.page.pageNo}">删除</a></td>
</tr>
</c:forEach>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a href="pages/manager/book_edit.jsp">添加图书</a></td>
</tr>
</table>
<%@ include file="/pages/common/page_nav.jsp"%>
</div>
<%@ include file="/pages/common/foot.jsp"%>
</body>
</html>
book_edit.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>编辑图书</title>
<%@ include file="/pages/common/head.jsp"%>
<style type="text/css">
h1 {
text-align: center;
margin-top: 200px;
}
h1 a {
color:red;
}
input {
text-align: center;
}
</style>
<script type="text/javascript">
$(function () {
$("#submit").click(function () {
var name = $("#name").val();
// alert(name);
if(name == ""){
alert("名称不能为空");
return false;
}
if($("#price").val() == ""){
alert("价格不能为空");
return false;
}
if($("#author").val() == ""){
alert("作者不能为空");
return false;
}
if($("#sales").val() == ""){
alert("销量不能为空");
return false;
}
if($("#stock").val() == ""){
alert("库存不能为空");
return false;
}
<%--var pageNo = ${param.pageNo};--%>
<%--alert(pageNo);--%>
<%--return;--%>
$.getJSON("admin/bookServlet",$("#form1").serialize(),function (data) {
alert(data.msg);
if(data.msg == "修改成功"){
location.href=${basePsth}"admin/bookServlet?action=page&pageNo="+${param.pageNo};
}
})
});
})
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="../../static/img/logo.gif" >
<span class="wel_word">编辑图书</span>
<%@ include file="/pages/common/manager_menu.jsp"%>
</div>
<div id="main">
<form action="book_manager.jsp" id="form1">
<input type="hidden" name="pageNo" value="${param.pageNo}">
<input type="hidden" name="action" value="${ empty param.id ? "add" : "update" }" />
<input type="hidden" name="id" value="${ requestScope.book.id }" />
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
<td><input name="name" type="text" id="name" value="${requestScope.book.name}"/></td>
<td><input name="price" type="text" id="price" value="${requestScope.book.price}"/></td>
<td><input name="author" type="text" id="author" value="${requestScope.book.author}"/></td>
<td><input name="sales" type="text" id="sales" value="${requestScope.book.sales}"/></td>
<td><input name="stock" type="text" id="stock" value="${requestScope.book.stock}"/></td>
<td><input type="button" value="提交" id="submit"/></td>
</tr>
</table>
</form>
</div>
<%@ include file="/pages/common/foot.jsp"%>
</body>
</html>
购物车模块
购物车信息保存在session中,不需要数据库。
编写car、carItem两个类
carItem:指的是购物车中的商品信息,每一个商品就是一个对象。改类有id、name、count、price、totalPrice五个属性。提供相应的get、set方法,空参和无参的构造器,tostring方法。
/**
* @author glq
* @create 2020-04-20 21:22
*/
public class CartItem {
private Integer id;
private String name;
private Integer count;
private BigDecimal price;
private BigDecimal totalPice;
public CartItem() {
}
public CartItem(Integer id, String name, Integer count, BigDecimal price, BigDecimal totalPice) {
this.id = id;
this.name = name;
this.count = count;
this.price = price;
this.totalPice = totalPice;
}
@Override
public String toString() {
return "CartItem{" +
"id=" + id +
", name='" + name + '\'' +
", count=" + count +
", price=" + price +
", totalPice=" + totalPice +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public BigDecimal getTotalPice() {
return totalPice;
}
public void setTotalPice(BigDecimal totalPice) {
this.totalPice = totalPice;
}
}
car是购物车类只有Map<Integer,CartItem> items一个属性。主要实现添加商品、删除商品、清空购物车、更新商品数量、获取商品总数、获取商品总价格这几个方法。
/**
* @author glq
* @create 2020-04-20 21:24
*/
public class Cart {
private Map<Integer,CartItem> items = new LinkedHashMap<>();
/**
* @Author glq
* @Description //TODO 添加商品
* @Date 9:19 2020/4/21
* @Param [cartItem]
* @return void
**/
public void addItem(CartItem cartItem){
CartItem item = items.get(cartItem.getId());
if(item == null){
items.put(cartItem.getId(),cartItem);
}else{
item.setCount( item.getCount() + 1 ); // 数量 累加
System.out.println("addItem");
item.setTotalPice(item.getPrice().multiply(new BigDecimal(item.getCount())));
}
}
/**
* @Author glq
* @Description //TODO 删除商品
* @Date 9:45 2020/4/21
* @Param [id]
* @return void
**/
public void deleteItem(Integer id){
items.remove(id);
}
/**
* @Author glq
* @Description //TODO 清空购物车
* @Date 9:46 2020/4/21
* @Param []
* @return void
**/
public void clear(){
items.clear();
}
/**
* @Author glq
* @Description //TODO 更新商品数量
* @Date 9:48 2020/4/21
* @Param [id, count]
* @return void
**/
public void updateCount(Integer id,Integer count){
CartItem cartItem = items.get(id);
if(cartItem != null){
cartItem.setCount(count);
cartItem.setTotalPice( cartItem.getPrice().multiply(new BigDecimal( cartItem.getCount() )) );
}
}
/**
* @Author glq
* @Description //TODO 获取商品总数
* @Date 9:48 2020/4/21
* @Param []
* @return java.lang.Integer
**/
public Integer getTotalCount(){
Integer totalCount = 0;
for(Map.Entry<Integer,CartItem> entry:items.entrySet()){
totalCount += entry.getValue().getCount();
}
return totalCount;
}
/**
* @Author glq
* @Description //TODO 获取商品总价格
* @Date 9:59 2020/4/21
* @Param []
* @return java.math.BigDecimal
**/
public BigDecimal getTotalPrice(){
BigDecimal totalPrice = new BigDecimal(0);
for(Map.Entry<Integer,CartItem> entry:items.entrySet()){
totalPrice = totalPrice.add(entry.getValue().getTotalPice());
}
return totalPrice;
}
@Override
public String toString() {
return "Cart{" +
"totalCount=" + getTotalCount() +
", totalPrice=" + getTotalPrice() +
", items=" + items +
'}';
}
public Map<Integer, CartItem> getItems() {
return items;
}
public void setItems(Map<Integer, CartItem> items) {
this.items = items;
}
}
编写CartServlet类
主要实现增删改清空购物车商品的功能
添加商品:首先获取商品id,根据id获得book信息,根据book构造一个cartItem对象,用于保存。然后获取session中的cart,若没有则创建,然后阿爸cartItem添加进去,最后将书名、总数量和总价格进行回显。
protected void addItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = WebUtils.parseInt(req.getParameter("id"), 0);
Book book = bookService.queryBookById(id);
CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart == null){
cart = new Cart();
req.getSession().setAttribute("cart",cart);
}
cart.addItem(cartItem);
req.getSession().setAttribute("lastName",cartItem.getName());
req.getSession().setAttribute("countPrice",cart.getTotalPrice());
HashMap<String, Object> map = new HashMap<>();
map.put("totalCount",cart.getTotalCount());
map.put("lastName",cartItem.getName());
Gson gson = new Gson();
String json = gson.toJson(map);
resp.getWriter().write(json);
}
删除商品、清空购物车、更新商品数量比较简单,判断一下是否为空然后直接处理即可。
/**
* @Author glq
* @Description //TODO 删除商品
* @Date 10:29 2020/4/21
* @Param [req, resp]
* @return void
**/
protected void deleteItem(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("deleteItem");
int id = WebUtils.parseInt(req.getParameter("id"), 0);
Cart cart = (Cart)req.getSession().getAttribute("cart");
if(cart != null){
cart.deleteItem(id);
}
req.getSession().setAttribute("countPrice",cart.getTotalPrice());
resp.sendRedirect(req.getHeader("Referer"));
}
/**
* @Author glq
* @Description //TODO 删除商品
* @Date 10:29 2020/4/21
* @Param [req, resp]
* @return void
**/
protected void clear(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("clear被调用");
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart != null){
cart.clear();
}
req.getSession().setAttribute("countPrice",cart.getTotalPrice());
resp.sendRedirect(req.getHeader("Referer"));
}
/**
* @Author glq
* @Description //TODO 修改商品数量
* @Date 10:33 2020/4/21
* @Param [req, resp]
* @return void
**/
protected void updateCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("updateCount");
int id = WebUtils.parseInt(req.getParameter("id"), 0);
int count = WebUtils.parseInt(req.getParameter("count"), 1);
Cart cart = (Cart) req.getSession().getAttribute("cart");
if(cart != null){
cart.updateCount(id,count);
}
req.getSession().setAttribute("countPrice",cart.getTotalPrice());
resp.sendRedirect(req.getHeader("Referer"));
}
修改jsp页面
cart.jsp:判断session中是否有商品信息,若没有则显示购物车为空的提示信息,若有则遍历显示,并且修改好删除标签的地址。然后将下面的购物车信息(商品数量、总金额)进行修改。修改清空购物车的链接。使用js判断商品数量发生修改以后发送ajax请求,更新商品数量。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>购物车</title>
<%@ include file="/pages/common/head.jsp"%>
<script type="text/javascript">
$(function () {
$(".updateCount").change(function () {
var id = $(this).attr('bookId');
var count = this.value;
location.href = "cartServlet?action=updateCount&count="+count+"&id="+id;
});
});
</script>
</head>
<body>
<div id="header">
<img class="logo_img" alt="" src="static/img/logo.gif" >
<span class="wel_word">购物车</span>
<%@ include file="/pages/common/login_sucess_menu.jsp"%>
</div>
<div id="main">
<table>
<tr>
<td>商品名称</td>
<td>数量</td>
<td>单价</td>
<td>金额</td>
<td>操作</td>
</tr>
<c:if test="${empty sessionScope.cart.items}">
<tr>
<td colspan="5"><a href="index.jsp">亲,当前购物车为空!快跟小伙伴们去浏览商品吧!!!</a> </td>
</tr>
</c:if>
<c:if test="${not empty sessionScope.cart.items}">
<c:forEach items="${sessionScope.cart.items}" var="entry">
<tr>
<td>${entry.value.name}</td>
<td><input class="updateCount" style="width: 80px;"
bookId="${entry.value.id}"
type="text" value="${entry.value.count}"></td>
<td>${entry.value.price}</td>
<td>${entry.value.totalPice}</td>
<td><a href="cartServlet?action=deleteItem&id=${entry.value.id}">删除</a></td>
</tr>
</c:forEach>
</c:if>
</table>
<div class="cart_info">
<span class="cart_span">购物车中共有<span class="b_count">${sessionScope.cart.totalCount}</span>件商品</span>
<span class="cart_span">总金额<span class="b_price">${sessionScope.countPrice}</span>元</span>
<span class="cart_span"><a href="cartServlet?action=clear">清空购物车</a></span>
<span class="cart_span"><a href="pages/cart/checkout.html">去结账</a></span>
</div>
</div>
<%@ include file="/pages/common/foot.jsp"%>
</body>
</html>
index.jsp中使用js判断加入购物车按钮点击了以后发送ajax请求,添加商品,然后获取返回的信息对显示的商品数量和加入购物车的商品名称进行显示。
$(function () {
$(".addToCart").click(function () {
var bookId = $(this).attr("bookId");
$.getJSON("cartServlet","action=addItem&id="+bookId,function (data) {
$("#cartTotalCount").text("您的购物车中有 " + data.totalCount + " 件商品");
$("#cartLastName").text(data.lastName);
})
});
});
测试
至此,用户图书和购物车模块的功能都已经完成了,测试一下是显示图示、修改图书、删除图书、添加图书,以及购物车的各种操作是否正常使用。