功能分析:
只有一個角色客戶,客戶可以
--查看圖書信息(包括查看圖書詳細信息,使用條件(例價格區間)查看圖書信息,對圖書進行翻頁)
--把圖書加入購物車
--查看購物車
--修改購物車(包括清空購物車,修改購物車單本圖書數量,刪除單本圖書)
--結賬(填寫用戶名和賬號信息)
--查看交易記錄
總體架構:
MVC 設計模式:
--model:POJO
--controller:Servlet
--view:JSP + EL + JSTL
技術選型:
數據庫:Mysql
數據源:C3P0
JDBC 工具:DBUtils
事務解決方案:Filter + ThreadLocal
Ajax 解決方案:jQuery + JavaScript + JSON + google-gson
層之間解耦方案:工廠設計模式
數據表設計:
在 Mysql 數據庫中建好這些數據表。
配置好環境
實體類設計:Account(賬戶表,用於支付),User(客戶表,存儲客戶基本信息),Trade(交易項),TradeItem(交易記錄),Book,ShoppingCartItem,ShoppingCart
DAO 層設計:(這里先每個方法手動的獲取Connection,在后面操作事務時,再改成獲取統一的Connection)
- Dao 接口,定義 Dao 的基本操作,使用BaseDao 實現 Dao 接口。
- BaseDao :使用 DBUtils 工具類提供 Dao 接口的具體實現。
BookDao 接口:用於定義操作 Book 實體類的基本方法。
- BookDaoImpl :使用 BaseDao 中的方法實現 BookDao。
Dao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import java.util.List; 4 5 /** 6 * Dao 接口,定義 Dao 的基本操作,由BaseDao 提供實現。 7 * @param <T>:Dao 實際操作的泛型類型。 8 */ 9 public interface Dao<T> { 10 11 /** 12 * 執行 update 操作(insert(但沒有返回值)、update、delete) 13 * @param sql:待執行的 SQL 語句。 14 * @param args:填充占位符的可變參數。 15 */ 16 void update(String sql, Object...args); 17 18 /** 19 * 執行 insert 操作,返回插入后的記錄的ID 20 * @param sql:待執行的 SQL 語句。 21 * @param args:填充占位符的可變參數。 22 * @return:插入新記錄的ID。 23 */ 24 long insert(String sql, Object...args); 25 26 /** 27 * 執行單條記錄的查詢,返回與記錄對應的類的一個對象。 28 * @param sql:待執行的SQL 語句。 29 * @param args:填充占位符的可變參數。 30 * @return:與記錄對應的類的一個對象。 31 */ 32 T query(String sql, Object...args); 33 34 /** 35 * 執行多條記錄的查詢,返回與記錄對應的類的一個List。 36 * @param sql:待執行的 SQL 語句。 37 * @param args:填充占位符的可變參數。 38 * @return:與記錄對應的類的一個 List。 39 */ 40 List<T> queryForList(String sql, Object...args); 41 42 /** 43 * 執行一個屬性或值得查詢,例如查詢某一條記錄的一個字段或查詢某個統計信息,返回要查詢的值。 44 * @param sql:待執行的 SQL 語句。 45 * @param args:填充占位符的可變參數。 46 * @return:返回要查詢的一個屬性或值。 47 */ 48 <E> E getForValue(String sql, Object...args); 49 50 /** 51 * 執行批量根性操作 52 * @param sql:待執行的 SQL 語句。 53 * @param params:填充占位符的可變參數。 54 */ 55 void batch(String sql, Object[]...params); 56 }
BookDao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import java.util.Collection; 4 import java.util.List; 5 6 import com.hnust.bookstore.domain.Book; 7 import com.hnust.bookstore.domain.ShoppingCartItem; 8 import com.hnust.bookstore.web.CriteriaBook; 9 import com.hnust.bookstore.web.Page; 10 11 public interface BookDao { 12 13 /** 14 * 根據 bookId 獲取指定的 Book 對象 15 * @param bookId 16 * @return 17 */ 18 public abstract Book getBook(int bookId); 19 20 /** 21 * 根據傳入的CriteriaBook 對象返回對應的 Page 對象。 22 * @param cb 23 * @return 24 */ 25 public abstract Page<Book> getPage(CriteriaBook cb); 26 27 /** 28 * 根據傳入的 CriteriaBook 對象返回對應的記錄個數。 29 * @param cb 30 * @return 31 */ 32 public abstract long getTotalBookNumber(CriteriaBook cb); 33 34 /** 35 * 根據傳入的 CriteriaBook 和 pageSize 返回當前頁對應的 List。 36 * @param cb 37 * @param pageSize 38 * @return 39 */ 40 public abstract List<Book> getPageList(CriteriaBook cb, int pageSize); 41 42 /** 43 * 返回指定的 id 的 book 的 storeNumber 字段的值。 44 * @param id 45 * @return 46 */ 47 public abstract int getStoreNumber(Integer bookId); 48 49 /** 50 * 根據傳入的 ShoppingCartItem 的集合, 51 * 批量更新 books 數據表的 storenumber 和 salesnumber 字段的值 52 * @param items 53 */ 54 public abstract void batchUpdateStoreNUmberAndSalesAmount(Collection<ShoppingCartItem> items); 55 }
AccountDao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import com.hnust.bookstore.domain.Account; 4 5 public interface AccountDao { 6 7 /** 8 * 根據傳入的 accountId 獲取對應的 Account 對象。 9 * @param accountId 10 * @return 11 */ 12 public abstract Account get(Integer accountId); 13 14 /** 15 * 根據傳入的 accountId、amount 更新指定賬戶的余額:扣除 amount 指定的錢數。 16 * @param accountId 17 * @param amount 18 */ 19 public abstract void updateBalance(Integer accountId, float amount); 20 }
TradeDao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import java.util.Set; 4 5 import com.hnust.bookstore.domain.Trade; 6 7 public interface TradeDao { 8 9 /** 10 * 向數據表中插入 Trade 對象 11 * @param trade 12 */ 13 public abstract void insert(Trade trade); 14 15 /** 16 * 根據 userId 獲取和其關聯的 Trade 的集合 17 * @param userId 18 * @return 19 */ 20 public abstract Set<Trade> getTradesWithUserId(Integer userId); 21 }
TradeItemDao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import java.util.Collection; 4 import java.util.Set; 5 6 import com.hnust.bookstore.domain.TradeItem; 7 8 public interface TradeItemDao { 9 10 /** 11 * 批量保存 TradeItem 對象 12 * @param items 13 */ 14 public abstract void batchSave(Collection<TradeItem> items); 15 16 /** 17 * 根據 tradeId 獲取和其關聯的 TradeItem 的集合。 18 * @param tradeId 19 * @return 20 */ 21 public abstract Set<TradeItem> getTradeItemsWithTradeId(Integer tradeId); 22 }
UserDao 接口 代碼:
1 package com.hnust.bookstore.dao; 2 3 import com.hnust.bookstore.domain.User; 4 5 public interface UserDao { 6 7 /** 8 * 根據用戶名獲取 User 對象。 9 * @param userName 10 * @return 11 */ 12 public abstract User getUser(String userName); 13 }
封裝翻頁信息的 Page 類:
-pageNo (當前頁的頁碼)
-list (本業需要顯示的 list (選購的書籍的集合))
-pageSize (每頁顯示多少條記錄)
-totalItemNumber (總的記錄數,用來計算總的頁數)
-Page(int) : 構造器,初始化當前頁的頁碼 pageNo,在Servlet 里面對其進行賦值。
-getPageNo():返回當前頁的頁碼,注意:需通過 getTatalPageNumber() 進行校驗,因為有可能傳入的頁碼不一定是合法的。
-getList():
-setList():設置當前頁需要顯示的 List 對象,是在 DAO 對其進行賦值。
-getPageSize():返回當前頁顯示多少條記錄
-getTotalPageNumber():獲取總頁碼數,需計算得出
-setTotalItemNumber():設置總的記錄數,是在 DAO 對其進行賦值。
-isHasNext()
-isHasPrev()
-getPrevPage()
-getNextPage()
封裝查詢條件的 CriteriaBook 類:
-minPrice:價格區間的最小值,默認為 0
-maxPrice:價格區間的最大值,默認為 Integer.MAX_VALUE
-pageNo:當前頁的頁碼
-CriteriaBook()
-CriteriaBook(int, int, int)
-getMinPrice()
-setMinPrice(int)
-getMaxPrice()
-setMaxPrice(int)
-getPageNo()
-setPageNo(int)
-toString()
BaseDao 代碼:
1 package com.hnust.bookstore.dao.impl; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.Statement; 7 import java.util.List; 8 9 import org.apache.commons.dbutils.QueryRunner; 10 import org.apache.commons.dbutils.handlers.BeanHandler; 11 import org.apache.commons.dbutils.handlers.BeanListHandler; 12 import org.apache.commons.dbutils.handlers.ScalarHandler; 13 14 import com.hnust.bookstore.dao.Dao; 15 import com.hnust.bookstore.db.JDBCUtils; 16 import com.hnust.bookstore.utils.ReflectionUtils; 17 import com.hnust.bookstore.web.ConnectionContext; 18 import com.sun.org.apache.regexp.internal.recompile; 19 20 public class BaseDao<T> implements Dao<T> { 21 22 private QueryRunner queryRunner = new QueryRunner(); 23 24 private Class<T> clazz; 25 26 public BaseDao(){ 27 clazz = ReflectionUtils.getSuperGenericType(getClass()); 28 } 29 30 @Override 31 public void update(String sql, Object... args) { 32 33 Connection conn = null; 34 35 try { 36 //獲取連接 37 conn = JDBCUtils.getConnection(); 38 queryRunner.update(conn, sql, args); 39 40 } catch (Exception e) { 41 e.printStackTrace(); } 42 }finally{ 43 JDBCUtils.release(conn); 44 } 45 } 46 47 @Override 48 public long insert(String sql, Object... args) { 49 50 long id = 0; 51 Connection conn = null; 52 PreparedStatement ps = null; 53 ResultSet rs = null; 54 55 try { 56 conn = JDBCUtils.getConnection(); 57 ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); 58 59 if(args != null){ 60 for(int i = 0; i < args.length; i++){ 61 ps.setObject(i + 1, args[i]); 62 } 63 } 64 ps.executeUpdate(); 65 //獲取生成的主鍵值 66 rs = ps.getGeneratedKeys(); 67 if(rs.next()){ 68 id = rs.getLong(1); 69 } 70 } catch (Exception e) { 71 e.printStackTrace(); 72 }finally{ 73 JDBCUtils.release(rs, ps); 74 JDBCUtils.release(conn); 75 } 76 return id; 77 } 78 79 @Override 80 public T query(String sql, Object... args) { 81 Connection conn = null; 82 83 try { 84 conn = JDBCUtils.getConnection(); 85 return queryRunner.query(conn, sql, new BeanHandler<>(clazz), args); 86 } catch (Exception e) { 87 e.printStackTrace(); 88 } 89 finally{ 90 JDBCUtils.release(conn); 91 } 92 return null; 93 } 94 95 @Override 96 public List<T> queryForList(String sql, Object... args) { 97 98 Connection conn = null; 99 try { 100 conn = JDBCUtils.getConnection(); 101 return queryRunner.query(conn, sql, new BeanListHandler<>(clazz), args); 102 } catch (Exception e) { 103 e.printStackTrace(); 104 } 105 finally{ 106 JDBCUtils.release(conn); 107 } 108 return null; 109 } 110 111 @Override 112 public <E> E getForValue(String sql, Object... args) { 113 Connection conn = null; 114 115 try { 116 conn = JDBCUtils.getConnection(); 117 return (E) queryRunner.query(conn, sql, new ScalarHandler(), args); 118 } catch (Exception e) { 119 e.printStackTrace(); 120 } 121 finally{ 122 JDBCUtils.release(conn); 123 } 124 return null; 125 } 126 127 @Override 128 public void batch(String sql, Object[]... params) { 129 Connection conn = null; 130 131 try { 132 conn = JDBCUtils.getConnection(); 133 queryRunner.batch(conn, sql, params); 134 } catch (Exception e) { 135 e.printStackTrace(); 136 } 137 finally{ 138 JDBCUtils.release(conn); 139 } 140 } 141 142 }
最后完成對以上剩余DAO層的實現,BookDaoImpl、AccountDaoImpl、TradeDaoImpl、TradeItemDaoImpl、UserDaoImpl。
明天繼續,over。