專案架構
- 三層架構:DAO(資料訪問)→ Service/ Servlet(業務邏輯)→ JSP(視圖)
- 核心功能:用戶註冊/登入、圖書分頁/搜尋、購物車、訂單生成/歷史、分頁顯示
核心模組代碼精要
1. 用戶註冊(DAO → Service → Servlet → JSP)
// UserDaoImpl.addUser()
String sql = "insert into user values(?,?,?,?)";
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setString(3, user.getEmail());
ps.setString(4, user.getAddress());
// RegisterServlet.doPost()
UserService dao = new UserServiceImpl();
boolean re = dao.register(user);
if (re) forward("register_success.jsp"); else forward("register.jsp");
2. 登入與 Cookie 記住帳號
// LoginServlet
String remember = request.getParameter("remember");
Cookie c1 = new Cookie("username", username);
Cookie c2 = new Cookie("password", password);
if ("on".equals(remember)) { c1.setMaxAge(300); c2.setMaxAge(300); }
else { c1.setMaxAge(0); c2.setMaxAge(0); }
response.addCookie(c1); response.addCookie(c2);
request.getSession().setAttribute("username", username);
3. 購物車(Session + Map + 實體封裝)
// BookShopping 實體:封裝 Book + count + totalPrice
public class BookShopping {
private Book book; private int count; private double totalprice;
public BookShopping(Book book, int count) {
this.book = book; this.count = count;
this.totalprice = book.getBookprice() * count;
}
}
// AddCartServlet:將 bookId 與數量存入 Session Map
Map<String, Integer> bookMap = (Map) session.getAttribute("bookMap");
for (String bid : bookIds) {
bookMap.put(bid, bookMap.getOrDefault(bid, 0) + 1);
}
session.setAttribute("bookMap", bookMap);
// shopping.jsp:JSTL 遍歷計算總價
<c:forEach var="obj" items="${bookshoppinglist}">
<td>${obj.book.bookname}</td>
<td>${obj.count}</td>
<td>${obj.book.bookprice}</td>
<td>${obj.totalprice}</td>
</c:forEach>
4. 訂單生成(Order + Items 多表關聯)
// OrderDaoImpl.addNewOrder():寫入 orders 表,回傳自增 oid
String sql = "insert into orders(date,user_name,state,totalmoney) values(?,?,?,?)";
// 執行後查詢剛插入的 oid
String q = "select oid from orders where date=? and user_name=? and state=? and totalmoney=?";
// OrderServlet:遍歷購物車生成 ItemsIn 批次寫入 items 表
List<ItemsIn> li = new ArrayList();
for (BookShopping bs : bookshoppinglist) {
ItemsIn in = new ItemsIn();
in.setO_id(oid); in.setBook_id(bs.getBook().getBookid());
in.setNumber(bs.getCount()); in.setSinglePrice(bs.getBook().getBookprice());
in.setSumMoney(bs.getTotalprice());
li.add(in);
}
new ItemDAOImp().insertItem(li);
5. 歷史訂單查詢(多表 JOIN + 分頁)
// ItemDAOImp.getPageList1():先查用戶所有 oid,再 IN 查詢 items+book+orders
String sql1 = "select oid from orders where user_name = ?";
// 拼接 oid 列表 → in (1,2,3)
String sql = "SELECT bookname,state,oid,DATE,user_name,summoney,bookimg,singleprice,number "
+ "FROM book,orders,items WHERE items.o_id=orders.oid AND items.book_id=book.bookid "
+ "AND orders.oid in(" + in + ") limit ?,?";
6. 通用分頁邏輯
// Servlet 統一處理
String count = request.getParameter("count"); // 每頁筆數
String curpage = request.getParameter("curpage"); // 當前頁
List<T> list = dao.getPageList(Integer.parseInt(curpage), Integer.parseInt(count));
int total = dao.getTotalcount();
int pageCount = (total + count - 1) / count;
request.setAttribute("list", list);
request.setAttribute("pagecount", pageCount);
request.setAttribute("currentPageIndex", curpage);
JSP 分頁導航條
<a href="MyItemsServlet?op=list&count=5&curpage=1">首頁</a>
<c:choose>
<c:when test="${currentPageIndex == 1}"><a href="#">上一頁</a></c:when>
<c:otherwise><a href="MyItemsServlet?op=list&count=5&curpage=${currentPageIndex-1}">上一頁</a></c:otherwise>
</c:choose>
<c:choose>
<c:when test="${currentPageIndex == pagecount}"><a href="#">下一頁</a></c:when>
<c:otherwise><a href="MyItemsServlet?op=list&count=5&curpage=${currentPageIndex+1}">下一頁</a></c:otherwise>
</c:choose>
<a href="MyItemsServlet?op=list&count=5&curpage=${pagecount}">尾頁</a>
技術亮點總結
- DAO 層封裝 JDBC、連接池、資源釋放
- Session 存儲購物車 Map,實體類封裝計算邏輯
- 訂單生成採用「主表+明細表」模式,JOIN 查詢歷史
- JSTL + EL 簡化 JSP,分頁邏輯抽取復用
- 前端 JS 校驗 + 後端 Servlet 校驗雙重保障