首页 > 代码库 > JavaWeb:网上书店的案例

JavaWeb:网上书店的案例

 

功能分析:

只有一个角色客户,客户可以

  --查看图书信息(包括查看图书详细信息,使用条件(例价格区间)查看图书信息,对图书进行翻页)

  --把图书加入购物车

  --查看购物车

  --修改购物车(包括清空购物车,修改购物车单本图书数量,删除单本图书)

  --结账(填写用户名和账号信息)

  --查看交易记录

总体架构:

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。

JavaWeb:网上书店的案例