必要に応じて書き換えはある程度自由にどうぞ # 備忘録 # 必要になるDB 1.商品一覧情報 m_item(最低限:**商品ID, 値段, 商品名,商品情報(説明文), 商品画像のパス**) 2.購入者側の情報 m_user(最低限:**ユーザID, ユーザ名, 所持ポイント**) 3.購入履歴の情報 m_history(最低限:**ユーザID, 商品ID**) 4.レビューの評価 m_review、内容(最低限:**ユーザID, 商品ID, 評価星(5段階), レビュータイトル, レビュー本文, 投稿月(タイムスタンプ)**) !!使用しない!! **×**2.出品者側の情報 m_seller(最低限:**出品者ID, パスワード**) **×**5.購入者のお気に入り情報 m_favorite(最低限:**ユーザID, 商品ID**) **×**6.問い合わせ内容の情報 m_contact(最低限:**ユーザID, 出品者ID, 問い合わせタイトル, 問い合わせ本文**) ※変更の可能性アリ. # 備忘 ①出品者に購入機能は無い ②購入しても実際にDBから商品が消えるわけではない ③問い合わせフォームへ遷移するページ -> 商品個別ページから""のみ""? ∵パワポ(6枚目)に記載 (0608追記) ④各ユーザごとに、『ポイント』の概念追加 ⑤商品レビューには、ユーザーが欲しいレビュー情報のみを検索できる機能を実装したい(検索方法は要相談) ↑本サービスのエッセンス機能? ⑥(追記求)レビューのガチャ機能 # ポイントの仕様 ①各ユーザにはそれぞれ、ポイントが付与される ②ポイントは、レビューを投稿することでユーザに付与される ③写真付きのレビューをすると、より多くのポイントを得る ④所有ポイントは、会計などに使用できる。 ⑤(要意見まとめ)累計獲得ポイントに応じて、ユーザはランク付け(ブロンズ、シルバー、ゴールドetc..)される。そのランクに応じて特典が付与される ⑥(要意見まとめ)商品レビューの表示される順番は、ポイントが高いユーザーから降順に表示されていく。 # 結局我々が実装したい部分は? ``` (画面機能ごとに分類した場合) ①ホーム画面 ②商品個別ページ画面(レビュー表示機能) ③レビュー詳細画面(レビュー投稿機能) ④ガチャを引く画面(ガチャの結果を表示し、ユーザのポイントに反映させる機能) ⑤カテゴリー一覧の画面及びカテゴリーで検索をかけた後の画面(カテゴリーに合った商品のみを表示する機能) ⑥ポイント確認画面(ユーザの所持ポイントを表示する機能) ``` ``` (役割ごとに分類した場合) ①Javaのコーデイング ②スマホ画面に対応したhtml, CSS部分の作成 ③プレゼン資料の作成 ``` # 必要となるUserDAOの機能 //レビューの新規投稿 //!!!reviewHead, reviewBody, reviewStar -> **userBean:Bean**で代替可能ではないか. insert(userId:String, itemId:String, reviewHead:String, reviewBody:String, reviewStar:int):UserBean //表示に関するDAO **itemDisplay**(user:UserBean):UserBean **reviewDisplay**(user:UserBean):UserBean **pointDisplay**(user:UserBean):UserBean //レビューの編集、及びポイントの加算に使用 **updateReview**(user:UserBean):int **updatePoint**(user:UserBean):int # 課題 レビューをset/getする方法がわからない(何bean.java でsetter/getterを定義すればよい?) # 必要なUserAction ※UserActionは**UserDAOを呼**び出す showItemInfo(商品IDに対応している商品名と商品画像を表示) → showReview (商品IDに対応しているレビュー一覧を取得&表示する) registerReview (商品IDに対応したレビューを**新規登録**する) updateReview (商品IDに対応した自分の**登録済み**レビューを書き換える) updatePoint (ポイントはガチャ結果に応じている) showPoint # UserDAO.java(0615.1500時点 ※一切テストしていません) ``` package model.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import model.entity.UserBean; public class UserDAO { //UserBean user -> String userId, String itemId public int insert(UserBean user, String itemId) throws SQLException, ClassNotFoundException{ int result = -1; //エラー条件 -> insert()のユーザIDと商品IDの組み合わせが既にDBに存在 try(Connection con = ConnectionManager.getConnection(); PreparedStatement errorCheckPrstat = con.prepareStatement("SELECT userId, itemId FROM m_review WHERE userId = ? AND itemId = ?")){ errorCheckPrstat.setString(1, user.getUserId()); errorCheckPrstat.setString(2, itemId); // sqlを実行 result = errorCheckPrstat.executeUpdate(); //result >= 1 -> 組み合わせ一致のDBがすでに存在 -> 新規レビュー投稿不可 if(result == 0){ try(PreparedStatement prstat = con.prepareStatement("INSERT INTO m_review values (?, ?, ?, ?, ?)")){ // プリペアドステートメントに値を設定 prstat.setString(1, user.getUserId()); prstat.setString(2, user.getUserBoughtItemId()); prstat.setInt(3, user.getUserReviewStar()); prstat.setString(4, user.getUserReviewHead()); prstat.setString(5, user.getUserReviewBody()); // sqlを実行 result = prstat.executeUpdate(); } }else{ throw new SQLException(); } } return result; } //selectAllつくる ""商品""に関する全情報 //ItemBeanつくる public List<ItemBean> selectAll() throws SQLException, ClassNotFoundException{ List<ItemBean> itemList = new ArrayList<>(); // コネクションマネージャーでDBに接続、プリペアドステートメント作成 try(Connection con = ConnectionManager.getConnection(); PreparedStatement prstat = con.prepareStatement("SELECT * FROM m_item")){ ResultSet result = prstat.executeQuery(); // customerListに実行結果を格納 while(result.next()) { ItemBean item = new ItemBean(); item.setItemId(result.getString("item_id")); item.setItemName(result.getString("item_name")); item.setItemPrice(result.getInt("item_price")); item.setItemExplanation(result.getString("item_explanation")); item.setItemImaPath(result.getString("item_imgPath")); itemList.add(item); } } return itemList; } //いらない public int updateReview(UserBean user) throws SQLException, ClassNotFoundException{ int result = 0; //userReview(Star, Head, Body)のいずれかが(null, 空)ならエラー if((1 > user.getUserReviewStar() || 5 < user.getUserReviewStar()) || (user.getUserReviewHead() == null || user.getUserReviewHead().equals("")) || (user.getUserReviewBody() == null || user.getUserReviewBody().equals(""))){ throw new SQLException(); }else{ //コネクションマネージャーでDBに接続、プリペアドステートメント作成 try(Connection con = ConnectionManager.getConnection(); PreparedStatement prstat = con.prepareStatement("UPDATE m_review SET user_review_star = ?," + "user_review_head = ?, user_review_body = ?")){ //プリペアドステートメントに値を設定 prstat.setInt(1, user.getUserReviewStar()); prstat.setString(2, user.getUserReviewHead()); prstat.setString(3, user.getUserReviewBody()); // sqlを実行 result = prstat.executeUpdate(); } } return result; } public int updatePoint(UserBean user) throws SQLException, ClassNotFoundException{ int result = 0; //コネクションマネージャーでDBに接続、プリペアドステートメント作成 try(Connection con = ConnectionManager.getConnection(); PreparedStatement prstat = con.prepareStatement("UPDATE m_user SET point = ?")){ //プリペアドステートメントに値を設定 prstat.setInt(1, user.getPoint()); // sqlを実行 result = prstat.executeUpdate(); } return result; } //select -> itemDisplay と reviewDisplay と pointDisplay //public UserBean itemDisplay(/* String 商品タグ, String 検索ワード */) throws SQLException, ClassNotFoundException{ // //検索機能は今回の実演で必要か? //} public UserBean reviewDisplay(int itemId) throws SQLException, ClassNotFoundException{ UserBean user = null; try(Connection con = ConnectionManager.getConnection(); PreparedStatement prstat = con.prepareStatement("SELECT * FROM m_review WHERE item_id = ?")){ // プリペアドステートメントに値を設定 prstat.setInt(1, itemId); // sqlを実行 ResultSet result = prstat.executeQuery(); //実行結果をreturn値に設定する //itemIDに合致すれば自分他人関わらずレビュー(星, タイトル, 本文)表示 user = new UserBean(); while(result.next()){ user.setUserReviewStar(result.getInt("user_review_star")); user.setUserReviewHead(result.getString("user_review_head")); user.setUserReviewBody(result.getString("user_review_body")); } } return user; } public int pointDisplay(UserBean user) throws SQLException, ClassNotFoundException{ int myPoint = 0; try(Connection con = ConnectionManager.getConnection(); PreparedStatement prstat = con.prepareStatement("SELECT * FROM m_user WHERE user_id = ?")){ prstat.setString(1, user.getUserId()); // sqlを実行 ResultSet result = prstat.executeQuery(); user = new UserBean(); while(result.next()){ user.setPoint(result.getInt("user_point")); } myPoint = user.getPoint(); } return myPoint; } } ``` # UserBean.java(0615.1500時点 ※一切テストしていません) package model.entity; import java.io.Serializable; public class UserBean implements Serializable { private String userId; private String password; //入れる必要は全くないけど入れないと佐藤さんにツッコミくらいそう. //private String userName; private int point; private String userReviewHead; private String userReviewBody; private Integer userReviewStar; private String userBoughtItemId; //!!!今回のお披露目範囲で必要かどうかわからない //private List<String> userFavorite; /** * 空のコンストラクタ */ public UserBean() { } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getPoint() { return point; } public void setPoint(int point) { this.point = point; } //!!!これで会っているかどうかわからない. DAO部分でListにしている public String getUserReviewHead() { return userReviewHead; } public void setUserReviewHead(String userReviewHead) { this.userReviewHead = userReviewHead; } public String getUserReviewBody() { return userReviewBody; } public void setUserReviewBody(String userReviewBody) { this.userReviewBody = userReviewBody; } public int getUserReviewStar() { return userReviewStar; } public void setUserReviewStar(int userReviewStar) { this.userReviewStar = userReviewStar; } public String getUserBoughtItemId(){ return userBoughtItemId; } public void setUserBoughtItemId(String userBoughtItemId){ this.userBoughtItemId = userBoughtItemId; } } # UserAction.java(0615.1645時点 ※一切テストしていません) ``` package model.action; import java.sql.SQLException; import java.util.List; import model.dao.UserDAO; import model.entity.ItemBean; import model.entity.UserBean; //itemDisplay, reviewDisplay, pointDisplay, updateReview, updatePoint, insert public class UserAction{ /* * レビューを投稿する(データベース m_review に要素を追加する) */ public int insert(UserBean user, String itemId) throws SQLException, ClassNotFoundException{ //レビューの入力フォームを空白で出すとnullではなく空で送信されるので、対策 if(1 > user.getUserReviewStar() || user.getUserReviewStar() > 5){ user.setUserReviewStar(-1); } if(user.getUserReviewHead().equals("")){ user.setUserReviewHead(null); } if(user.getUserReviewBody().equals("")){ user.setUserReviewBody(null); } UserDAO dao = new UserDAO(); return dao.insert(user, itemId); //return int } public List<ItemBean> selectAllItem() throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.selectAllItem(); } //いらない public int updateReview(UserBean user) throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.updateReview(user); //return int } /* *ガチャで得たポイントを加算する */ public int updatePoint(UserBean user) throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.updatePoint(user); } /* * 商品IDで検索したレビューを表示する */ public UserBean reviewDisplay(String itemId) throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.reviewDisplay(itemId); } /* * ユーザが所持しているポイントを表示する */ public int pointDisplay(UserBean user) throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.pointDisplay(user); //return int. } /* * 商品個別ページで必要な情報(商品ID、商品名、値段、説明文、画像)を商品IDで検索して m_item から取得する */ public ItemBean itemDisplay(String itemId) throws SQLException, ClassNotFoundException{ UserDAO dao = new UserDAO(); return dao.itemDisplay(itemId); } } ``` # 6/15 メモ HOME画面が追加されるので、それに伴って追加(①、②) ①DBから、selectAllで商品をとってきて、**HOME画面で全部表示**する →dao, actionにselectAll追加して ②ホーム画面から商品個別ページに飛ぶとき、 **商品IDを引き継ぐサーブレット**を挟んで飛ぶようにする ③個別ページから個別レビューに飛ぶときは、 m_review を商品IDで検索(サーブレットで商品IDを引き継ぎ、サーブレット内部でDAOを用いて m_review 内部を検索) ④reviewDisplay の return :UserBean -> List<UserBean>にする ⑤レビューは新規投稿のみ → メソッド updateReview は**いらない** ⑥insertについて、 引数をBeanにするか、 個々の情報(商品ID、レビューの星、本文etc..)を引数で指定するか UserDAOの各メソッドは手分けして作成の方針 updatePoint()を入れてください # SQL文(ユーザー、テーブル作成) ``` /*DB作成*/ DROP DATABASE IF EXISTS pet_sys_db; CREATE DATABASE pet_sys_db CHARACTER SET utf8 COLLATE utf8_general_ci; /*ユーザを作成*/ DROP USER IF EXISTS embexU; CREATE USER embexU IDENTIFIED BY 'embexP'; /*権限付与*/ GRANT ALL PRIVILEGES ON pet_sys_db. * TO embexU; /*AUTOCOMMIT無効*/ SET AUTOCOMMIT=0; /*DB選択*/ USE pet_sys_db; /*ユーザマスタ作成*/ CREATE TABLE pet_sys_db.m_user ( user_id VARCHAR(24) PRIMARY KEY, user_name VARCHAR(24) NOT NULL, user_point INT NOT NULL ); INSERT INTO m_user VALUES('Nekokko01', 'メルカリ太郎', 50); INSERT INTO m_user VALUES('Inuinnu02', 'ヤフオク花子', 100); INSERT INTO m_user VALUES('Petpet03', '桃ペイペイ', 10); /*商品マスタ作成*/ CREATE TABLE pet_sys_db.m_item ( item_id CHAR(5) PRIMARY KEY , item_name VARCHAR(24) NOT NULL , item_price INT NOT NULL, item_explanation VARCHAR(400), item_img_path VARCHAR(400) ); INSERT INTO m_item (item_id, item_name, item_price, item_explanation) VALUES('A0001', '大型犬用極太首輪', '5000', '大型犬の飼い主さんにぜひどうぞ!'); INSERT INTO m_item (item_id, item_name, item_price, item_explanation) VALUES('C0002', '子犬用おしゃれハウス', '10000', '赤屋根に乗せられるウッドストックのマスコット付き!'); INSERT INTO m_item (item_id, item_name, item_price, item_explanation) VALUES('D0003', 'ニャンまるもキャットタワー', '15000', '引っ掛かりの良い麻縄ボールはボロボロろになっても球の位置を入れ替えて長く使えます!'); /*商品レビューマスタ作成*/ CREATE TABLE pet_sys_db.m_review ( user_id VARCHAR(24) NOT NULL, item_id CHAR(5) NOT NULL, review_star TINYINT unsigned NOT NULL, /*unsigned: 0-255 評価に負数が入らないように */ review_head VARCHAR(40) NOT NULL, review_body VARCHAR(400) NOT NULL, purchase_datetime TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY(item_id) REFERENCES pet_sys_db.m_item(item_id) ); INSERT INTO m_review (user_id, item_id, review_star, review_head, review_body) VALUES('Nekokko01', 'D0003', '5', 'うちの猫がますます可愛くなりました', '我が家のねこ達はみんな夢中で遊んでくれています。'); INSERT INTO m_review (user_id, item_id, review_star, review_head, review_body) VALUES('Inuinnu02', 'A0001', '5', '大型犬の力でも負けない!', '犬への負担も少なそうで買ってよかったと思います。大型犬の飼い主さんにはおススメです!'); INSERT INTO m_review (user_id, item_id, review_star, review_head, review_body) VALUES('Petpet03', 'C0002', '5', '想像以上に可愛いです!', '最初からなんの抵抗もなく、気に入ったようですぐに寝ちゃいました。'); /* 購入履歴マスタ作成 */ /* 初期状態では、レビューを投稿 した/してない に関わらず全て表示します */ CREATE TABLE m_history ( user_id VARCHAR(24) PRIMARY KEY, item_id CHAR(5) NOT NULL ); INSERT INTO m_history VALUES('Nekokko01', 'D0003'); INSERT INTO m_history VALUES('Inuinnu02', 'A0001'); INSERT INTO m_history VALUES('Petpet03', 'C0002'); COMMIT; ```