一. 储备知识
在项目中使用EL+JSTL遍历显示图书数据,主要分为两大部分:完成管理员端的增删改查功能;完成用户访问index页面的图书的显示和按照加个查询指定数据的功能。本篇首先讲述第一个功能。
1.1 完成管理员端的增删改查功能
前面设计了一个三层架构来优化Servlet处理请求,所以这次介绍的功能也同样使用三层架构来实现。
变现层:用户交互的内容
- book_manager.jsp:提供图书处理的页面给管理员查看
- BookManagerServlet extends BaseServlet:用来处理管理员增删改查图书的操作(访问Servlet时必须携带type参数,值要与方法名相同,方法的结构必须与doGet一样)
BookManagerServlet中的方法 | 解释 |
---|---|
getAllBooks() | 获取所有图书 |
getBook() | 获取一本图书 |
updateBook() | 修改图书的信息 |
deleteBook() | 删除指定的图书 |
addBook() | 添加图书 |
业务层:处理图书的业务逻辑(连接显示层和DAO层)
- 创建一个名为BookService的interface来约束对图书的操作
BookService中的方法 | 解释 |
---|---|
List<Book> getAllBooks(); | 获取所有图书 |
Book getBook(String bookId); | 根据图书id查询一本图书,因为Servlet传回来的参数param中都是String类型(包含图书的id也是String),所以在传入方法的参数时, 我们传入String类型的id,而不是int类型的id |
boolean updateBook(Book book); | 传入修改后的图书信息,要修改的图书id |
boolean deleteBook(String bookId); | 根据指定id删除一本书 |
boolean addBook(Book book); | 添加图书 |
- 创建一个BookServiceImpl来实现BookService接口
DAO层:和数据库交互
- 创建一个名为BookDao的interface来约束对数据库中book表的操作
BookDao中的方法 | 解释 |
---|---|
List<Book> getAllBooks(); | 查询所有图书的方法 |
Book getBookById(String bookId); | 根据指定id来查询图书 |
int updateBookById(Book book); | 根据id来更新图书信息 |
deleteBookById(String bookId); | 删除id对应的图书 |
boolean saveBook(Book book); | 保存图书 |
注意:
以上步骤完成了三层架构,但是还有最重要的两个步骤需要完成:建表和建实体类
建表:
- 建立名为book的表,字段有id,title(书名),author(作者),price(单价),sales(销量),stock(库存),img_path(保存图书封面的路径)。id,sales,stock为int;price为double;其余为String。代码啊如下:
CREATE TABLE book(
id INTEGER(11) PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL,
price DOUBLE(11,2),
sales INT(11),
stock INT(11),
img_path VARCHAR(100)
);
建实体类:
- 根据book表建立名为Book的实体类。id,sales,stock为int;price为double;其余为String
二. 源码例子
Book.java
package com.atguigu.bookstore.bean;
import java.io.Serializable;
public class Book implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;//图书标号
private String title;//图书标题
private String author;//作者
private String imgPath;//图书封面的路径
private double price;//单价
private Integer sales;//销量
private Integer stock;//库存
public Book() {
super();
// TODO Auto-generated constructor stub
}
public Book(Integer id, String title, String imgPath, double price, Integer sales, Integer stock) {
super();
this.id = id;
this.title = title;
this.imgPath = imgPath;
this.price = price;
this.sales = sales;
this.stock = stock;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getImgPath() {
return imgPath;
}
public void setImgPath(String imgPath) {
this.imgPath = imgPath;
}
public double getPrice() {
return price;
}
public void setPrice(double 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;
}
@Override
public String toString() {
return "Book [id=" + id + ", title=" + title + ", imgPath=" + imgPath + ", price=" + price + ", sales=" + sales
+ ", stock=" + stock + "]";
}
}
BookDao.java
package com.atguigu.bookstore.dao;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
/**
* 约束对表book的操作
* @author user
*
*/
public interface BookDao {
/**
* 查询所有图书的方法
*/
List<Book> getAllBooks();
/**
* 查询指定id对应的图书
*/
Book getBookById(String bookId);
/**
* 保存图书
* book参数除了id没有,其他属性都有
*/
int saveBook(Book book);
/**
* 删除id对应的图书
*/
int deleteBookById(String bookId);
/**
* 根据id更新图书
* book参数肯定包含id和图书的其他信息
* 数据库中根据id查找到需要修改的图书数据,然后使用book对象的所有属性值替换数据库中的数据
*/
int updateBookById(Book book);
}
BookDaoImpl.java
package com.atguigu.bookstore.dao.impl;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.dao.BaseDao;
import com.atguigu.bookstore.dao.BookDao;
public class BookDaoImpl extends BaseDao implements BookDao{
@Override
public List<Book> getAllBooks() {
// TODO Auto-generated method stub
String sql = "select id, title, author, price, sales, stock, img_path imgPath"
+ " from book";
return getBeanList(Book.class, sql);
}
@Override
public Book getBookById(String bookId) {
// TODO Auto-generated method stub
String sql = "select id, title, author, price, sales, stock, img_path imgPath"
+ " from book where id = ?";
return getBean( Book.class, sql, bookId);
}
@Override
public int saveBook(Book book) {
// TODO Auto-generated method stub
String sql = "insert into book(title, author, price, sales, stock, "
+ "img_path ) values(?, ?, ?, ?, ?, ?)";
return update(sql, book.getTitle(), book.getAuthor(), book.getPrice(), book.getSales(),
book.getStock(), book.getImgPath());
}
@Override
public int deleteBookById(String bookId) {
// TODO Auto-generated method stub
String sql = "delete from book where id = ?";
return update(sql, bookId);
}
@Override
public int updateBookById(Book book) {
// TODO Auto-generated method stub
String sql = "update book set title=?, author=?, price=?, sales=?, stock=?,"
+ " img_path=? where id = ?";
return update(sql, book.getTitle(), book.getAuthor(), book.getPrice(), book.getSales(),
book.getStock(), book.getImgPath(), book.getId());
}
}
BookService.java
package com.atguigu.bookstore.service;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
/**
* 规定对图书操作的业务方法
* @author user
*
*/
public interface BookService {
/**
* 查询所有的图书集合
*/
List<Book> getAllBooks();
/**
* 删除图书的业务方法
* @return
*/
boolean deleteBook(String bookId);
/**
* 添加图书的业务方法
*/
boolean addBook(Book book);
/**
* 查询指定图书的业务方法
* @return
*/
Book getBook(String bookId);
/**
* 修改指定图书数据的方法
* book参数,携带了id和修改后的图书数据
* @return
*/
boolean updateBook(Book book);
}
BookServiceImpl.java
package com.atguigu.bookstore.service.impl;
import java.util.List;
import com.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.dao.BookDao;
import com.atguigu.bookstore.dao.impl.BookDaoImpl;
import com.atguigu.bookstore.service.BookService;
public class BookServiceImpl implements BookService{
//Service层与数据交互必须通过Dao层实现
private BookDao dao = new BookDaoImpl();
@Override
public List<Book> getAllBooks() {
// TODO Auto-generated method stub
return dao.getAllBooks();
}
@Override
public boolean deleteBook(String bookId) {
// TODO Auto-generated method stub
return dao.deleteBookById(bookId)>0;
}
@Override
public boolean addBook(Book book) {
// TODO Auto-generated method stub
return dao.saveBook(book)>0;
}
@Override
public Book getBook(String bookId) {
// TODO Auto-generated method stub
return dao.getBookById(bookId);
}
@Override
public boolean updateBook(Book book) {
// TODO Auto-generated method stub
return dao.updateBookById(book)>0;
}
}
BookManagerServlet.java
package com.atguigu.bookstore.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
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 org.apache.commons.beanutils.BeanUtils;
import com.atguigu.bookstore.bean.Book;
import com.atguigu.bookstore.service.BookService;
import com.atguigu.bookstore.service.impl.BookServiceImpl;
import com.atguigu.bookstore.utils.WebUtils;
/**
* Servlet implementation class BookManagerServlet
*/
public class BookManagerServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
private BookService service = new BookServiceImpl();
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void getAllBooks(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.获取请求参数
//2.调用其他类处理业务
List<Book> list = service.getAllBooks();
//将数据存到域中共享
request.setAttribute("list", list);
//3.给用户响应[转发(使用request域进行转发)、重定向、response对象向响应体写入内容]
//将集合数据交给book_manager.jsp页面显示
//转发到book_manager.jsp
request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request, response);
}
}
book_manager.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
<%@ include file="/WEB-INF/include/base.jsp" %>
<script type="text/javascript">
/*给删除超链接绑定删除事件*/
$(function(){
$(".delA").click(function(){
//由于a标签遍历显示图书时会产生多个,所以不能使用id属性
//获取被点击的a标签所在行的第一个单元格的文本内容,即a标签的爹(td标签)的爹(tr标签)的第一个儿子(即tr中的第一个td标签)
//this为a标签的dom对象,$(this)为将dom对象转换为jquery对象
var title = $(this).parents("tr").children("td:eq(0)").text();
if(! confirm("你真的要删除《" + title + "》吗?")){
//取消删除,阻止a标签的默认行为
return false;
}
});
});
</script>
</head>
<body>
<div id="header">
<div class="logo_content">
<div class="logo_img">
<img src="static/img/baozhatanglogo.jpg" alt="" width="30px">
</div>
<span>欢迎来到一流爆炸糖书城</span>
</div>
<div class="header_content">
<a href="">设置</a> |
<a href="">退出</a>
</div>
</div>
<div id="main">
<c:choose>
<c:when test="${empty requestScope.list }">
<%-- ${empty requestScope.list } 判断查询所有的图书集合 --%>
<h3 style="color:red; text-align:center; margin-top: 150px;">没有图书数据!赶紧去添加吧!<a href="pages/manager/book_add.jsp">添加图书</a></h3>
</c:when>
<c:otherwise>
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<!-- 遍历图书集合,每本图书数据对应一行显示 -->
<c:forEach items="${list }" var="book">
<td>${book.title }</td>
<td>${book.price }</td>
<td>${book.author }</td>
<td>${book.sales }</td>
<td>${book.stock }</td>
<td><a href="pages/manager/book_edit.jsp">修改</a></td>
<td><a class="delA" href="BookManagerServlet?type=deleteBook&bookId=${book.id }">删除</a></td>
</c:forEach>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td><a href="pages/manager/book_add.jsp">添加图书</a></td>
</tr>
</table>
</c:otherwise>
</c:choose>
</div>
<div id="bottom">
<span>
一流爆炸糖书城.Copyright ©2019
</span>
</div>
</body>
</html>