[TOC]
# 步驟 1 : 先運行,看到效果,再學習
先將完整的項目(向老師要相關資料),配置運行起來,確認可用之后,再學習做了哪些步驟以達到這樣的效果。
# 步驟 2 : 模仿和排錯
在確保可運行項目能夠正確無誤地運行之后,再嚴格照著教程的步驟,對代碼模仿一遍。
模仿過程難免代碼有出入,導致無法得到期望的運行結果,此時此刻通過比較**正確答案** ( 可運行項目 ) 和自己的代碼,來定位問題所在。
采用這種方式,**學習有效果,排錯有效率**,可以較為明顯地提升學習速度,跨過學習路上的各個檻。
# 步驟 3 : 頁面截圖
重啟tomcat,通過訪問地址
`http://127.0.0.1:8080/tmall_j2ee/admin_product_list?cid=12`
可以看到產品管理的界面
注: 這cid=12是分類的id,根據你的實際運行情況,采取不同的id值

# 步驟 4 : 在分類管理頁面上添加產品管理的超鏈
接下來講, 接著上一步**屬性管理可運行項目**做了哪些工作以支持產品管理的操作。
首先,在listCategory.jsp里,加上產品管理這一列

```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<script>
$(function(){
$("#addForm").submit(function(){
if(!checkEmpty("name","分類名稱"))
return false;
if(!checkEmpty("categoryPic","分類圖片"))
return false;
return true;
});
});
</script>
<title>分類管理</title>
<div class="workingArea">
<h1 class="label label-info" >分類管理</h1>
<br>
<br>
<div class="listDataTableDiv">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>圖片</th>
<th>分類名稱</th>
<th>屬性管理</th>
<th>產品管理</th>
<th>編輯</th>
<th>刪除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${thecs}" var="c">
<tr>
<td>${c.id}</td>
<td><img height="40px" src="img/category/${c.id}.jpg"></td>
<td>${c.name}</td>
<td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td>
<td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%@include file="../include/admin/adminPage.jsp" %>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增分類</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data">
<table class="addTable">
<tr>
<td>分類名稱</td>
<td><input id="name" name="name" type="text" class="form-control"></td>
</tr>
<tr>
<td>分類圖片</td>
<td>
<input id="categoryPic" accept="image/*" type="file" name="filepath" />
</td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.jsp"%>
```
# 步驟 5: 修改實體類Product.java
1\. 與數據庫相關字段一一對應的基本屬性
2\. 與Category的多對一關系
3\. firstProductImage這個屬性,用于顯示這個產品的默認圖片,所以需要查詢產品單個圖片。
> 產品管理需要用到默認圖片

```
package com.dodoke.bean;
import java.util.Date;
/*******************************************************************************
* javaBeans t_product --> TProduct <table explanation>
*
* @author 2019-01-17 08:35:28
*
*/
public class Product {
// field
/** ID **/
private int id;
/** 名稱 **/
private String name;
/** 子標題 **/
private String subTitle;
/** 原價格 **/
private float originalPrice;
/** 促銷價 **/
private float promotePrice;
/** 倉庫 **/
private int stock;
/** 創建時間 **/
private Date createDate;
/** 所屬分類 **/
private Category category;
private ProductImage firstProductImage;
// method
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public float getOriginalPrice() {
return originalPrice;
}
public void setOriginalPrice(float originalPrice) {
this.originalPrice = originalPrice;
}
public float getPromotePrice() {
return promotePrice;
}
public void setPromotePrice(float promotePrice) {
this.promotePrice = promotePrice;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public ProductImage getFirstProductImage() {
return firstProductImage;
}
public void setFirstProductImage(ProductImage firstProductImage) {
this.firstProductImage = firstProductImage;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", subTitle=" + subTitle + ", originalPrice=" + originalPrice
+ ", promotePrice=" + promotePrice + ", stock=" + stock + ", createDate=" + createDate + ", category="
+ category + "]";
}
}
```
# 步驟 6: 產品圖片ProductImage
1\. 基礎屬性的getter、setter
2\. **與Product的多對一關系**
```
package com.dodoke.bean;
/*******************************************************************************
* javaBeans t_product_image --> TProductImage <table explanation>
*
* @author 2019-01-17 08:35:28
*
*/
public class ProductImage {
// field
/** ID **/
private int id;
/** 類型 **/
private String type;
/** 所屬產品 **/
private Product product;
// method
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
@Override
public String toString() {
return "ProductImage [id=" + id + ", type=" + type + ", product=" + product + "]";
}
}
```
# 步驟 7: ProductDao
ProductDao::
```
package com.dodoke.dao.inter;
import java.util.List;
import com.dodoke.bean.Product;
public interface ProductDao {
/**
* 增加
*
* @param product
*/
public void add(Product product);
/**
* 刪除
*
* @param id
*/
public void delete(int id);
/**
* 修改
*
* @param product
*/
public void update(Product product);
/**
* 根據id獲取
*
* @param id
* @return
*/
public Product get(int id);
/**
* 某個分類下的產品分頁查詢
*
* @param cid
* @param start
* @param count
* @return
*/
public List<Product> list(int cid, int start, int count);
/**
* 查詢某個分類下的所有產品
*
* @return
*/
public List<Product> list(int cid);
/**
* 獲取某個分類下的產品總數
*
* @return
*/
public int getTotal(int cid);
}
```
# 步驟 8: ProductImageDao
兩種靜態屬性分別表示單個圖片和詳情圖片
```
public static final String type\_single = "type\_single";
public static final String type\_detail = "type\_detail";
```
```
package com.dodoke.dao.inter;
import java.util.List;
import com.dodoke.bean.Product;
import com.dodoke.bean.ProductImage;
public interface ProductImageDao {
public static final String type_single = "type_single";
public static final String type_detail = "type_detail";
/**
* 增加
*
* @param productImage
*/
public void add(ProductImage productImage);
/**
* 刪除
*
* @param id
*/
public void delete(int id);
/**
* 修改
*
* @param productImage
*/
public void update(ProductImage productImage);
/**
* 根據id獲取
*
* @param id
* @return
*/
public ProductImage get(int id);
/**
* 某個產品下的產品圖片分頁查詢
*
* @param product
* @param start
* @param count
* @param type
* 單個圖片/詳情圖片
* @return
*/
public List<ProductImage> list(Product product, String type, int start, int count);
/**
* 查詢某個產品下的所有產品圖片
*
* @return
*/
public List<ProductImage> list(Product product, String type);
/**
* 獲取某個產品下的產品圖片總數
*
* @return
*/
public int getTotal(int cid);
}
```
# 步驟 9: ProductImageDaoImpl
```
package com.dodoke.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.dodoke.bean.Product;
import com.dodoke.bean.ProductImage;
import com.dodoke.dao.inter.ProductImageDao;
import com.dodoke.util.DBUtil;
public class ProductImageDaoImpl implements ProductImageDao {
private ProductDaoImpl productDao = new ProductDaoImpl();
@Override
public void add(ProductImage bean) {
String sql = "insert into t_product_image(type,product_id) values(?,?)";
try (Connection c = DBUtil.getConnection();
PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
ps.setString(1, bean.getType());
ps.setInt(2, bean.getProduct().getId());
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
bean.setId(id);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void delete(int id) {
String sql = "delete from t_product_image where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(ProductImage productImage) {
// TODO Auto-generated method stub
}
@Override
public ProductImage get(int id) {
ProductImage bean = new ProductImage();
String sql = "select * from t_product_image where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int pid = rs.getInt("product_id");
String type = rs.getString("type");
Product product = productDao.get(pid);
bean.setProduct(product);
bean.setType(type);
bean.setId(id);
}
} catch (SQLException e) {
e.printStackTrace();
}
return bean;
}
@Override
public List<ProductImage> list(Product p, String type, int start, int count) {
List<ProductImage> beans = new ArrayList<ProductImage>();
String sql = "select * from t_product_image where product_id =? and type =? order by id desc limit ?,? ";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, p.getId());
ps.setString(2, type);
ps.setInt(3, start);
ps.setInt(4, count);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
ProductImage bean = new ProductImage();
int id = rs.getInt("id");
bean.setProduct(p);
bean.setType(type);
bean.setId(id);
beans.add(bean);
}
} catch (SQLException e) {
e.printStackTrace();
}
return beans;
}
@Override
public List<ProductImage> list(Product p, String type) {
return list(p, type, 0, Short.MAX_VALUE);
}
@Override
public int getTotal(int cid) {
return 0;
}
}
```
# 步驟 10: ProductDaoImpl類
一個產品有多個圖片,但是只有一個主圖片,把第一個圖片設置為主圖片
```
public void setFirstProductImage(Product p)
```
ProductDaoImpl:
```
package com.dodoke.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.dodoke.bean.Category;
import com.dodoke.bean.Product;
import com.dodoke.bean.ProductImage;
import com.dodoke.dao.inter.ProductDao;
import com.dodoke.dao.inter.ProductImageDao;
import com.dodoke.util.DBUtil;
import com.dodoke.util.DateUtil;
public class ProductDaoImpl implements ProductDao {
private CategoryDaoImpl categoryDao = new CategoryDaoImpl();
@Override
public void add(Product bean) {
String sql = "insert into t_product(name,sub_title,original_price,promote_price,stock,create_date,category_id) values(?,?,?,?,?,?,?)";
try (Connection c = DBUtil.getConnection();
PreparedStatement ps = c.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);) {
ps.setString(1, bean.getName());
ps.setString(2, bean.getSubTitle());
ps.setFloat(3, bean.getOriginalPrice());
ps.setFloat(4, bean.getPromotePrice());
ps.setInt(5, bean.getStock());
ps.setTimestamp(6, DateUtil.d2t(bean.getCreateDate()));
ps.setInt(7, bean.getCategory().getId());
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
bean.setId(id);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void delete(int id) {
String sql = "delete from t_product where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void update(Product bean) {
String sql = "update t_product set name= ?, sub_title=?, original_price=?,promote_price=?,stock=?, category_id = ?, create_date=? where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setString(1, bean.getName());
ps.setString(2, bean.getSubTitle());
ps.setFloat(3, bean.getOriginalPrice());
ps.setFloat(4, bean.getPromotePrice());
ps.setInt(5, bean.getStock());
ps.setInt(6, bean.getCategory().getId());
ps.setTimestamp(7, DateUtil.d2t(bean.getCreateDate()));
ps.setInt(8, bean.getId());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public Product get(int id) {
Product bean = new Product();
String sql = "select * from t_product where id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, id);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String name = rs.getString("name");
String subTitle = rs.getString("sub_title");
float originalPrice = rs.getFloat("original_price");
float promotePrice = rs.getFloat("promote_price");
int stock = rs.getInt("stock");
int cid = rs.getInt("category_id");
Date createDate = DateUtil.t2d(rs.getTimestamp("create_date"));
bean.setName(name);
bean.setSubTitle(subTitle);
bean.setOriginalPrice(originalPrice);
bean.setPromotePrice(promotePrice);
bean.setStock(stock);
Category category = categoryDao.get(cid);
bean.setCategory(category);
bean.setCreateDate(createDate);
bean.setId(id);
setFirstProductImage(bean);
}
} catch (SQLException e) {
e.printStackTrace();
}
return bean;
}
public void setFirstProductImage(Product p) {
List<ProductImage> pis = new ProductImageDaoImpl().list(p, ProductImageDao.type_single);
if (!pis.isEmpty()) {
p.setFirstProductImage(pis.get(0));
}
}
@Override
public List<Product> list(int cid) {
return list(cid, 0, Short.MAX_VALUE);
}
@Override
public List<Product> list(int cid, int start, int count) {
List<Product> beans = new ArrayList<Product>();
Category category = categoryDao.get(cid);
String sql = "select * from t_product where category_id = ? order by id desc limit ?,? ";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, cid);
ps.setInt(2, start);
ps.setInt(3, count);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Product bean = new Product();
int id = rs.getInt("id");
String name = rs.getString("name");
String subTitle = rs.getString("sub_title");
float originalPrice = rs.getFloat("original_price");
float promotePrice = rs.getFloat("promote_price");
int stock = rs.getInt("stock");
Date createDate = DateUtil.t2d(rs.getTimestamp("create_date"));
bean.setName(name);
bean.setSubTitle(subTitle);
bean.setOriginalPrice(originalPrice);
bean.setPromotePrice(promotePrice);
bean.setStock(stock);
bean.setCreateDate(createDate);
bean.setId(id);
bean.setCategory(category);
setFirstProductImage(bean);
beans.add(bean);
}
} catch (SQLException e) {
e.printStackTrace();
}
return beans;
}
@Override
public int getTotal(int cid) {
int total = 0;
String sql = "select count(*) from t_product where category_id = ?";
try (Connection c = DBUtil.getConnection(); PreparedStatement ps = c.prepareStatement(sql);) {
ps.setInt(1, cid);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
total = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return total;
}
}
```
# 步驟 11: ProductServlet類
```
package com.dodoke.controller;
import java.util.List;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dodoke.bean.Category;
import com.dodoke.bean.Product;
import com.dodoke.util.Page;
/**
* Servlet implementation class ProductServlet
*/
@WebServlet("/ProductServlet")
public class ProductServlet extends BaseBackServlet {
private static final long serialVersionUID = 1L;
@Override
public String add(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
String name = request.getParameter("name");
String subTitle = request.getParameter("subTitle");
float originalPrice = Float.parseFloat(request.getParameter("originalPrice"));
float promotePrice = Float.parseFloat(request.getParameter("promotePrice"));
int stock = Integer.parseInt(request.getParameter("stock"));
Product p = new Product();
p.setCategory(c);
p.setName(name);
p.setSubTitle(subTitle);
p.setOriginalPrice(originalPrice);
p.setPromotePrice(promotePrice);
p.setStock(stock);
productDao.add(p);
return "@admin_product_list?cid=" + cid;
}
@Override
public String delete(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Product p = productDao.get(id);
productDao.delete(id);
return "@admin_product_list?cid=" + p.getCategory().getId();
}
@Override
public String edit(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Product p = productDao.get(id);
request.setAttribute("p", p);
return "admin/editProduct.jsp";
}
@Override
public String update(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
int id = Integer.parseInt(request.getParameter("id"));
int stock = Integer.parseInt(request.getParameter("stock"));
float originalPrice = Float.parseFloat(request.getParameter("originalPrice"));
float promotePrice = Float.parseFloat(request.getParameter("promotePrice"));
String subTitle = request.getParameter("subTitle");
String name = request.getParameter("name");
Product p = new Product();
p.setName(name);
p.setSubTitle(subTitle);
p.setOriginalPrice(originalPrice);
p.setPromotePrice(promotePrice);
p.setStock(stock);
p.setId(id);
p.setCategory(c);
productDao.update(p);
return "@admin_product_list?cid=" + p.getCategory().getId();
}
@Override
public String list(HttpServletRequest request, HttpServletResponse response, Page page) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
List<Product> ps = productDao.list(cid, page.getStart(), page.getCount());
int total = productDao.getTotal(cid);
page.setTotal(total);
page.setParam("&cid=" + c.getId());
request.setAttribute("ps", ps);
request.setAttribute("c", c);
request.setAttribute("page", page);
return "admin/listProduct.jsp";
}
}
```
# 步驟12: listProduct.jsp和editProduct.jsp
listProduct.jsp
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<script>
$(function() {
$("#addForm").submit(function() {
if (!checkEmpty("name", "產品名稱"))
return false;
// if (!checkEmpty("subTitle", "小標題"))
// return false;
if (!checkNumber("originalPrice", "原價格"))
return false;
if (!checkNumber("promotePrice", "優惠價格"))
return false;
if (!checkInt("stock", "庫存"))
return false;
return true;
});
});
</script>
<title>產品管理</title>
<div class="workingArea">
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分類</a></li>
<li><a href="admin_product_list?cid=${c.id}">${c.name}</a></li>
<li class="active">產品管理</li>
</ol>
<div class="listDataTableDiv">
<table
class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr class="success">
<th>ID</th>
<th>圖片</th>
<th>產品名稱</th>
<th>產品小標題</th>
<th width="53px">原價格</th>
<th width="80px">優惠價格</th>
<th width="80px">庫存數量</th>
<th width="80px">圖片管理</th>
<th width="80px">設置屬性</th>
<th width="42px">編輯</th>
<th width="42px">刪除</th>
</tr>
</thead>
<tbody>
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id}</td>
<td>
<c:if test="${!empty p.firstProductImage}">
<img width="40px" src="img/productSingle/${p.firstProductImage.id}.jpg">
</c:if>
</td>
<td>${p.name}</td>
<td>${p.subTitle}</td>
<td>${p.originalPrice}</td>
<td>${p.promotePrice}</td>
<td>${p.stock}</td>
<td><a href="admin_productImage_list?pid=${p.id}"><span
class="glyphicon glyphicon-picture"></span></a></td>
<td><a href="admin_propertyValue_editPropertyValue?id=${p.id}"><span
class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_edit?id=${p.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true"
href="admin_product_delete?id=${p.id}"><span
class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="pageDiv">
<%@include file="../include/admin/adminPage.jsp"%>
</div>
<div class="panel panel-warning addDiv">
<div class="panel-heading">新增產品</div>
<div class="panel-body">
<form method="post" id="addForm" action="admin_product_add">
<table class="addTable">
<tr>
<td>產品名稱</td>
<td><input id="name" name="name" type="text"
class="form-control"></td>
</tr>
<tr>
<td>產品小標題</td>
<td><input id="subTitle" name="subTitle" type="text"
class="form-control"></td>
</tr>
<tr>
<td>原價格</td>
<td><input id="originalPrice" value="99.98" name="originalPrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>優惠價格</td>
<td><input id="promotePrice" value="19.98" name="promotePrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>庫存</td>
<td><input id="stock" value="99" name="stock" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="cid" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</div>
<%@include file="../include/admin/adminFooter.jsp"%>
```
editProduct.jsp
```
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@include file="../include/admin/adminHeader.jsp"%>
<%@include file="../include/admin/adminNavigator.jsp"%>
<title>編輯產品</title>
<script>
$(function() {
$("#editForm").submit(function() {
if (!checkEmpty("name", "產品名稱"))
return false;
// if (!checkEmpty("subTitle", "小標題"))
// return false;
if (!checkNumber("originalPrice", "原價格"))
return false;
if (!checkNumber("promotePrice", "優惠價格"))
return false;
if (!checkInt("stock", "庫存"))
return false;
return true;
});
});
</script>
<div class="workingArea">
<ol class="breadcrumb">
<li><a href="admin_category_list">所有分類</a></li>
<li><a href="admin_product_list?cid=${p.category.id}">${p.category.name}</a></li>
<li class="active">${p.name}</li>
<li class="active">編輯產品</li>
</ol>
<div class="panel panel-warning editDiv">
<div class="panel-heading">編輯產品</div>
<div class="panel-body">
<form method="post" id="editForm" action="admin_product_update">
<table class="editTable">
<tr>
<td>產品名稱</td>
<td><input id="name" name="name" value="${p.name}"
type="text" class="form-control"></td>
</tr>
<tr>
<td>產品小標題</td>
<td><input id="subTitle" name="subTitle" type="text"
value="${p.subTitle}"
class="form-control"></td>
</tr>
<tr>
<td>原價格</td>
<td><input id="originalPrice" value="${p.originalPrice}" name="originalPrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>優惠價格</td>
<td><input id="promotePrice" value="${p.promotePrice}" name="promotePrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>庫存</td>
<td><input id="stock" value="${p.stock}" name="stock" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
<button type="submit" class="btn btn-success">提 交</button></td>
</tr>
</table>
</form>
</div>
</div>
</div>
```
# 步驟 13 : 查詢功能講解
查詢訪問的是ProductServlet的list()方法
1\. 獲取分類 cid
2\. 基于cid,獲取當前分類下的產品集合
3\. 獲取當前分類下的產品總數,并且設置給分頁page對象
4\. 拼接字符串"&cid="+c.getId(),設置給page對象的Param值。 因為產品分頁都是基于當前分類下的分頁,所以分頁的時候需要傳遞這個cid
5\. 把產品集合設置到 request的 "ps" 屬性上
6\. 把分類對象設置到 request的 "c" 屬性上
7\. 把分頁對象設置到 request的 "page" 對象上
8\. 服務端跳轉到admin/listProduct.jsp頁面
9\. 在listProduct.jsp頁面上使用c:forEach 遍歷ps集合,并顯示
ProductServlet片段:
```
@Override
public String list(HttpServletRequest request, HttpServletResponse response, Page page) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
List<Product> ps = productDao.list(cid, page.getStart(), page.getCount());
int total = productDao.getTotal(cid);
page.setTotal(total);
page.setParam("&cid=" + c.getId());
request.setAttribute("ps", ps);
request.setAttribute("c", c);
request.setAttribute("page", page);
return "admin/listProduct.jsp";
}
```
listProduct.jsp:
```
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id}</td>
<td>
<c:if test="${!empty p.firstProductImage}">
<img width="40px" src="img/productSingle/${p.firstProductImage.id}.jpg">
</c:if>
</td>
<td>${p.name}</td>
<td>${p.subTitle}</td>
<td>${p.originalPrice}</td>
<td>${p.promotePrice}</td>
<td>${p.stock}</td>
<td><a href="admin_productImage_list?pid=${p.id}"><span
class="glyphicon glyphicon-picture"></span></a></td>
<td><a href="admin_product_editPropertyValue?id=${p.id}"><span
class="glyphicon glyphicon-th-list"></span></a></td>
<td><a href="admin_product_edit?id=${p.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td><a deleteLink="true"
href="admin_product_delete?id=${p.id}"><span
class=" glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
```
# 步驟 14 : 增加功能講解
1\. 在listProduct.jsp提交數據的時候,除了提交產品名稱,小標題,原價格,優惠價格,庫存外還會提交cid
2\. 在ProductServlet中根據獲取到的cid,name,subTitle,等參數,創建新的Product對象,并插入到數據庫
3\. 客戶端跳轉到admin\_product\_list,并帶上參數cid

listProduct.jsp
```
<form method="post" id="addForm" action="admin_product_add">
<table class="addTable">
<tr>
<td>產品名稱</td>
<td><input id="name" name="name" type="text"
class="form-control"></td>
</tr>
<tr>
<td>產品小標題</td>
<td><input id="subTitle" name="subTitle" type="text"
class="form-control"></td>
</tr>
<tr>
<td>原價格</td>
<td><input id="originalPrice" value="99.98" name="originalPrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>優惠價格</td>
<td><input id="promotePrice" value="19.98" name="promotePrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>庫存</td>
<td><input id="stock" value="99" name="stock" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="cid" value="${c.id}">
<button type="submit" class="btn btn-success">提 交</button>
</td>
</tr>
</table>
</form>
```
ProductServlet
```
@Override
public String add(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
String name = request.getParameter("name");
String subTitle = request.getParameter("subTitle");
float originalPrice = Float.parseFloat(request.getParameter("originalPrice"));
float promotePrice = Float.parseFloat(request.getParameter("promotePrice"));
int stock = Integer.parseInt(request.getParameter("stock"));
Product p = new Product();
p.setCategory(c);
p.setName(name);
p.setSubTitle(subTitle);
p.setOriginalPrice(originalPrice);
p.setPromotePrice(promotePrice);
p.setStock(stock);
productDao.add(p);
return "@admin_product_list?cid=" + cid;
}
```
# 步驟 15 : 編輯功能講解
1\. 在ProductServlet的edit方法中,根據id獲取Product對象
2\. 把Product對象放在request的 "p" 屬性中
3\. 服務端跳轉到admin/editProduct.jsp
4\. 在editProduct.jsp中顯示屬性名稱
5\. 在editProduct.jsp中隱式提供id和cid
ProductServlet
```
@Override
public String edit(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Product p = productDao.get(id);
request.setAttribute("p", p);
return "admin/editProduct.jsp";
}
```
editProduct
```
<form method="post" id="editForm" action="admin_product_update">
<table class="editTable">
<tr>
<td>產品名稱</td>
<td><input id="name" name="name" value="${p.name}"
type="text" class="form-control"></td>
</tr>
<tr>
<td>產品小標題</td>
<td><input id="subTitle" name="subTitle" type="text"
value="${p.subTitle}"
class="form-control"></td>
</tr>
<tr>
<td>原價格</td>
<td><input id="originalPrice" value="${p.originalPrice}" name="originalPrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>優惠價格</td>
<td><input id="promotePrice" value="${p.promotePrice}" name="promotePrice" type="text"
class="form-control"></td>
</tr>
<tr>
<td>庫存</td>
<td><input id="stock" value="${p.stock}" name="stock" type="text"
class="form-control"></td>
</tr>
<tr class="submitTR">
<td colspan="2" align="center">
<input type="hidden" name="id" value="${p.id}">
<input type="hidden" name="cid" value="${p.category.id}">
<button type="submit" class="btn btn-success">提 交</button></td>
</tr>
</table>
</form>
```
# 步驟 16: 修改功能講解
1\. 在ProductServlet的update方法中獲取cid,id, name,subTitle,price等參數
2\. 根據這些參數創建Product對象
3\. 借助productDAO更新這個對象到數據庫
4\. 客戶端跳轉到admin\_product\_list,并帶上參數cid

```
public String update(HttpServletRequest request, HttpServletResponse response) {
int cid = Integer.parseInt(request.getParameter("cid"));
Category c = categoryDao.get(cid);
int id = Integer.parseInt(request.getParameter("id"));
int stock = Integer.parseInt(request.getParameter("stock"));
float originalPrice = Float.parseFloat(request.getParameter("originalPrice"));
float promotePrice = Float.parseFloat(request.getParameter("promotePrice"));
String subTitle = request.getParameter("subTitle");
String name = request.getParameter("name");
Product p = new Product();
p.setName(name);
p.setSubTitle(subTitle);
p.setOriginalPrice(originalPrice);
p.setPromotePrice(promotePrice);
p.setStock(stock);
p.setId(id);
p.setCategory(c);
productDao.update(p);
return "@admin_product_list?cid=" + p.getCategory().getId();
}
```
# 步驟 17 : 刪除功能講解
1\. 在ProductServlet的delete方法中獲取id
2\. 根據id獲取Product對象
3\. 借助productDAO刪除這個對象對應的數據
4\. 客戶端跳轉到admin\_product\_list,并帶上參數cid
```
public String delete(HttpServletRequest request, HttpServletResponse response) {
int id = Integer.parseInt(request.getParameter("id"));
Product p = productDao.get(id);
productDao.delete(id);
return "@admin_product_list?cid=" + p.getCategory().getId();
}
```
- 項目簡介
- 功能一覽
- 前臺
- 后臺
- 開發流程
- 需求分析-展示
- 首頁
- 產品頁
- 分類頁
- 搜索結果頁
- 購物車查看頁
- 結算頁
- 確認支付頁
- 支付成功頁
- 我的訂單頁
- 確認收貨頁
- 評價頁
- 頁頭信息展示
- 需求分析-交互
- 分類頁排序
- 立即購買
- 加入購物車
- 調整訂單項數量
- 刪除訂單項
- 生成訂單
- 訂單頁功能
- 確認付款
- 確認收貨
- 提交評價信息
- 登錄
- 注冊
- 退出
- 搜索
- 前臺需求列表
- 需求分析后臺
- 分類管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性設置
- 用戶管理
- 訂單管理
- 后臺需求列表
- 表結構設計
- 數據建模
- 表與表之間的關系
- 實體類設計
- DAO類設計
- 工具類
- CategoryDao設計
- Service業務類設計
- 后臺-分類管理
- 可運行的項目
- 靜態資源
- FILTER配合SERVLET
- JSP包含關系
- 查詢
- 分頁
- 增加
- 刪除
- 編輯
- 修改
- 后臺其他管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性值設置
- 用戶管理
- 訂單管理