Java MVCフレームワークでショッピング風サイトを作る(Model 編)
Java MVCフレームワークでショッピング風サイトを作る(Model 編)
Java MVCフレームワークでショッピング風サイトを作って見たのでメモ。 今回はModel 編。前回View編の続き。
環境
仕様・構成
-
「ログイン画面(index.jsp)」からあらかじめDBに保存しているユーザIDをパスワードを使ってログインする。
-
「商品一覧画面(itemList.jsp)」へ遷移するので、 商品一覧の中から購入数(あらかじめ決めた在庫数まで)を選択して、購入ボタンを選択。
-
すると、 「購入確認画面(confirm_result.jsp)」へ遷移し、 購入ボタンをまた選択する。
-
商品が購入され、「購入結果画面(result.jsp)」へ遷移し、
-
一覧へ戻るを選択して、「商品一覧画面(itemList.jsp)」へ戻ってくる(在庫数は再計算されている)
また、購入履歴を選択した場合は、 過去に何を買ったかを「購入履歴画面(history.jsp)」へ遷移する。
商品を買う場合のActivity図
商品を買う場合のActivity図は、以下のようになる。
ログイン側では、モデルLoginUserBean とDAOクラスLoginDao を使用する。
商品一覧側では、モデルItemBean とDAOクラスShoppingDaoを使う。
購入履歴側では、モデルHistoryBean とDAOクラスShoppingDaoを使う。
状態(画面)遷移図
状態遷移図で表すと以下のようになる。
Model(Beanクラス)とDAOファイルの確認
今回使うModel は3種類、 DAOクラスは2種類。
クラス名 | 説明 |
---|---|
LoginUserBean.java | ログインユーザ情報を格納 |
ItemBean.java | 商品情報を格納 |
HistoryBean.java | 購入履歴を格納 |
クラス名 | 説明 |
---|---|
LoginDao.java | ログイン処理用DB処理 |
ShoppingDAO.java | 購入処理用DB処理 |
Model(Bean)の作成
LoginUserBean.java
ログインユーザ情報を格納するモデル。 以前作ったものと同じ。
フィールドとして、以下の3つ。
-
ユーザID(
id_
) -
ユーザの名前(
name_
) -
ユーザの年齢(
age_
)
ログイン処理は、コントローラであるLoginServletで行う。
package login;
import java.io.Serializable;
public class LoginUserBean implements Serializable {
private static final long serialVersionUID = 1L;
private String id_;
private String name_;
private int age_;
public LoginUserBean() {
this.id_ = "";
this.name_ = "";
this.age_ = 0;
}
public LoginUserBean(String id, String name, int age) {
this.id_ = id;
this.name_ = name;
this.age_ = age;
}
public void setId(String id){
this.id_ = id;
}
public String getId(){
return this.id_;
}
public void setName(String name){
this.name_ = name;
}
public String getName(){
return this.name_;
}
public void setAge(int age){
this.age_ = age;
}
public int getAge(){
return this.age_;
}
}
ItemBean.java
商品情報を格納する。 フィールドは、以下の4つ。
-
商品ID(
item_id_
) -
商品名(
item_name_
) -
商品の値段(
price_
) -
商品の在庫数(
quantity_
)
商品情報のリストは、ArrayList<ItemBean>
などで格納できる。
package shopping;
import java.io.Serializable;
public class ItemBean implements Serializable {
private static final long serialVersionUID = 1L;
private String item_id_;
private String item_name_;
private int price_;
private int quantity_;
public ItemBean() {
this.item_id_ = "";
this.item_name_ = "";
this.price_ = 0;
this.quantity_ = 0;
}
public ItemBean(String item_id, String item_name, int price, int quantity) {
this.item_id_ = item_id;
this.item_name_ = item_name;
this.price_ = price;
this.quantity_ = quantity;
}
public void setItemId(String item_id) {
this.item_id_ = item_id;
}
public String getItemId() {
return this.item_id_;
}
public void setItemName(String item_name) {
this.item_name_ = item_name;
}
public String getItemName() {
return this.item_name_;
}
public void setPrice(int price) {
this.price_ = price;
}
public int getPrice() {
return this.price_;
}
public void setQuantity(int quantity) {
this.quantity_ = quantity;
}
public int getQuantity() {
return this.quantity_;
}
}
HistoryBean.java
購入履歴を格納する。 フィールドは、以下の3つ。
-
商品ID(
item_id_
) -
商品名(
item_name_
) -
購入した数(
quantity_
)
package shopping;
import java.io.Serializable;
/**
* HistoryBean
*/
public class HistoryBean implements Serializable {
private static final long serialVersionUID = 1L;
private String item_id_; // 商品ID
private String item_name_; // 商品名
private int quantity_; // 購入した数
public HistoryBean() {
this.item_id_ = "";
this.item_name_ = "";
this.quantity_ = 0;
}
public HistoryBean(String item_id, String item_name, int quantity) {
this.item_id_ = item_id;
this.item_name_ = item_name;
this.quantity_ = quantity;
}
public void setItemId(String item_id){
this.item_id_ = item_id;
}
public String getItemId(){
return this.item_id_;
}
public void setItemName(String item_name){
this.item_name_ = item_name;
}
public String getItemName(){
return this.item_name_;
}
public void setQuantity(int quantity){
this.quantity_ = quantity;
}
public int getQuantity(){
return this.quantity_;
}
}
DAOクラスの作成
DAOクラスは、ユーザ情報を持つuserテーブルにアクセスするLoginDao と 商品情報(itemテーブル)と購入履歴(historyテーブル)にアクセスするShoppingDao の2種類。
LoginDao.java
userテーブルにアクセスする。
コンストラクタで、 JDBCドライバでMySQLデータベースに接続する。
ResultSet selectUser(String id, String pass)
メソッドで、 ユーザIDとパスワードの照会を行う。
package login;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* ログインDAOクラス.
*/
public class LoginDao {
private Connection con_ = null;
private ResultSet rs_ = null;
private PreparedStatement ps_ = null;
public LoginDao() throws SQLException {
try {
// JDBCドライバのロード
// 「com.mysql.jdbc.Driver」クラス名
Class.forName("com.mysql.jdbc.Driver");
// データベースと接続(本来はユーザやパスワードも別管理にしておくのが理想)
this.con_ = DriverManager.getConnection("jdbc:mysql://localhost:3306/shopping_sample",
"user",
"password");
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
/**
* データベースから指定されたIDとパスワードを使ってユーザ情報を検索します.
*
* @param id ログインID
* @param pass パスワード
* @return ユーザ情報(ResultSet)
* @throws SQLException
*/
public ResultSet selectUser(String id, String pass) throws SQLException {
// SQL文を生成
this.ps_ = this.con_.prepareStatement("select name, age from user where id = ? and pass = ?");
// 生成したSQL文の「?」の部分にIDとパスワードをセット
this.ps_.setString(1, id);
this.ps_.setString(2, pass);
// SQLを実行
this.rs_ = this.ps_.executeQuery();
return this.rs_;
}
/**
* コネクションをクローズします.
*/
public void close() {
try {
// データベースとの接続を解除する
if (this.con_ != null) {
this.con_.close();
}
if (this.ps_ != null) {
this.ps_.close();
}
if (this.rs_ != null) {
this.rs_.close();
}
} catch (SQLException se) {
// データベースとの接続解除に失敗した場合
se.printStackTrace();
}
}
}
ShoppingDao.java
商品情報(itemテーブル)、在庫(stockテーブル)と購入履歴(historyテーブル)にアクセスする。
ResultSet selectItem()
メソッドで、itemテーブルに登録されているすべての商品とstockテーブルから商品情報とその在庫数を返す。
ResultSet selectItem(String item_id)
メソッドで、 その商品IDを元に、itemテーブルとstockテーブルから商品情報とその在庫数を返す。
ResultSet selectHistory(String user_id)
メソッドで、 ユーザIDを元に、historyテーブルからそのユーザ購入履歴情報を返す。
void updateItem(String item_id, int purchased_num)
メソッドで、 商品が購入された場合に、 stockテーブルの在庫数を更新する。
void updateHistory(String user_id, String item_id, int purchased_num)
メソッドで、商品が購入された場合に、historyテーブルで商品履歴を更新する。
package shopping;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* ショッピング風DAOクラス. DBの商品(item)テーブルと購入履歴(history)のテーブルを扱う
*/
public class ShoppingDao {
private Connection con_ = null;
private ResultSet rs_ = null;
private PreparedStatement ps_ = null;
public ShoppingDao() throws SQLException {
// JDBCドライバのロード
try {
// 「com.mysql.jdbc.Driver」クラス名
Class.forName("com.mysql.jdbc.Driver");
// データベースと接続(本来はユーザやパスワードも別管理にしておくのが理想)
this.con_ = DriverManager.getConnection("jdbc:mysql://localhost:3306/shopping_sample",
"user",
"password");
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
}
/**
* データベースの全商品と在庫を取得します.
*
* @return 商品情報(ResultSet)
* @throws SQLException
*/
public ResultSet selectItem() throws SQLException {
// SQL文を生成
this.ps_ = this.con_.prepareStatement(
"select item.item_id, item.item_name, item.price, stock.quantity from item inner join stock on item.item_id = stock.item_id"
);
// SQLを実行
this.rs_ = this.ps_.executeQuery();
return this.rs_;
}
/**
* 商品IDを基にデータベースの商品情報と在庫を取得します.
*
* @return 商品情報(ResultSet)
* @param item_id 商品ID
* @throws SQLException
*/
public ResultSet selectItem(String item_id) throws SQLException {
// SQL文を生成
this.ps_ = this.con_.prepareStatement(
"select item.item_name, item.price, stock.quantity from item inner join stock on item.item_id = stock.item_id where item.item_id = ?"
);
// SQL文に商品IDを設定
this.ps_.setString(1, item_id);
// SQLを実行
this.rs_ = this.ps_.executeQuery();
return this.rs_;
}
/**
* ユーザの購入履歴を取得します.
*
* @param user_id
* @return 購入履歴(ResultSet)
* @throws SQLException
*/
public ResultSet selectHistory(String user_id) throws SQLException {
// SQL文を生成
this.ps_ = this.con_.prepareStatement("select history.item_id, item.item_name, history.quantity from history inner join item on history.id = ? and history.item_id = item.item_id");
this.ps_.setString(1, user_id);
// SQLを実行
this.rs_ = this.ps_.executeQuery();
return this.rs_;
}
/**
* 商品IDを基にデータベースの在庫を更新(マイナス)します.
*
* @param item_id;
* @param purchased_num 購入数
* @throws SQLException
*/
public void updateItem(String item_id, int purchased_num) throws SQLException {
// SQL文を生成
/* update文を追加
在庫から購入数を引く
*/
this.ps_ = this.con_.prepareStatement("update stock set quantity = quantity - ? where item_id = ?");
// SQL文に数量を設定
this.ps_.setInt(1, purchased_num);
// SQL文に商品IDを設定
this.ps_.setString(2, item_id);
// SQLを実行
this.ps_.executeUpdate();
}
/**
* 購入履歴テーブルを更新します.
*
* @param user_id ユーザID
* @param item_id 商品ID
* @param purchased_num 購入数
* @throws SQLException
*/
public void updateHistory(String user_id, String item_id, int purchased_num) throws SQLException {
// SQL文を生成
this.ps_ = this.con_.prepareStatement("insert into history(id, item_id, quantity) values (?, ?, ?)");
this.ps_.setString(1, user_id);
this.ps_.setString(2, item_id);
this.ps_.setInt(3, purchased_num);
this.ps_.executeUpdate();
}
/**
* コネクションをクローズします.
*/
public void close() {
try {
// データベースとの接続を解除する
if (this.con_ != null) {
this.con_.close();
}
if (this.ps_ != null) {
this.ps_.close();
}
if (this.rs_ != null) {
this.rs_.close();
}
} catch (SQLException se) {
// データベースとの接続解除に失敗した場合
se.printStackTrace();
}
}
}
コード
参考リンク
-
Java入門 -ショッピング風サイトの作成①- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus
-
Java入門 -ショッピング風サイトの作成②- 井野 雄貴 先生 - 無料動画学習|schoo(スクー)WEB-campus