はじめに
初めまして。佐藤佑哉です。
今回は授業の中でMVCモデルの説明があったので、備忘録として残したいなと思います。気になる箇所があったらコメントなどよろしくお願い致します!
環境
Apache NetBEans IDE:15
Java:17.0.4.1
Windows11・バージョン10.0
MySQL:8.0.31
MVCモデルとは
役割毎にModel,View,Controllerに分割してコーディングを行うモデル
- Model:システム中でビジネスロジックを担当
- View:表示や入出力と行った処理を担当
- Controller:ユーザの入力に基づき、ModelとViewを制御
引用:https://qiita.com/s_emoto/items/975cc38a3e0de462966a
MVCモデル概念図
動作
今回は授業課題として自分なりのWebページを作るというもので、値段管理リストを作ってみました。
動作は次のようになります。
実装
データベース:MySQL
実際、外部キーとか設定していますが、結局有効活用していないような気がします笑
値段テーブル
- management_id:値段管理ID(主キー)
- merchandise_id:商品ID(外部キー)
- shop_id:店(外部キー)
mysql> desc price;
+----------------+------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------+------+-----+---------+----------------+
| management_id | int | NO | PRI | NULL | auto_increment |
| merchandise_id | int | NO | MUL | NULL | |
| shop_id | int | NO | MUL | NULL | |
| created_at | date | NO | | NULL | |
| price | int | NO | | NULL | |
+----------------+------+------+-----+---------+----------------+
商品テーブル
- merchandise_id:商品ID
- merchandise_name:商品名
- created_at:商品の登録日
mysql> desc merchandise;
+------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+----------------+
| merchandise_id | int | NO | PRI | NULL | auto_increment |
| merchandise_name | varchar(20) | NO | | NULL | |
| created_at | date | NO | | NULL | |
+------------------+-------------+------+-----+---------+----------------+
店テーブル
- shop_id:店ID
- shop_name:店名
- created_at:店の登録日
mysql> desc shop;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| shop_id | int | NO | PRI | NULL | auto_increment |
| shop_name | varchar(20) | NO | | NULL | |
| created_at | date | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
View:jsp
値段管理リスト:(UIは前述の写真の通り)
コードの詳細(クリックすると表示されます)
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!-- 商品テーブルのクラスを宣言 --><jsp:useBean id="merchandise" scope="session" class="final_task.MerchandiseDb"/>
<!-- 店テーブルのクラスを宣言 --><jsp:useBean id="shop" scope="session" class="final_task.ShopDb" />
<!-- 結合テーブルのクラスを宣言 --><jsp:useBean id="combined" scope="session" class="final_task.ConbinedPriceDb" />
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>値段管理リスト</title>
<style>
p{
color: blue;
}
</style>
</head>
<body>
<div >
<h1>値段管理リスト</h1>
<!-- 値段を登録するフォーム -->
<form method="post" action="<%=request.getContextPath()%>/RegisterPriceSer">
<!-- 値段を記入する項目(Object:値段) -->
<input type="number" name="register_price" value="0" placeholder="値段を記入して下さい"/>
<!-- 商品を選択するプルダウンリスト(Object:商品ID) -->
<select name="register_merchandise_id">
<option value="-1">商品を選択して下さい</option>
<% for (int i = 0; i < merchandise.getDataNum(); i++) {%>
<option value="<%=merchandise.getMerchandiseId(i)%>"><%=merchandise.getMerchandiseName(i)%></option>
<%}%>
</select>
<!-- 店を選択するプルダウンリスト (Object:店ID)-->
<select name="register_shop_id">
<option value="-1">店を選択して下さい</option>
<% for (int i = 0; i < shop.getDataNum(); i++) {%>
<option value="<%=shop.getShopId(i)%>"><%=shop.getShopName(i)%></option>
<%}%>
</select>
<!-- 登録ボタン -->
<input type="submit" value="登録"/>
<!-- ページリストに戻るボタン -->
<input type="button" value="戻る" onclick="location.herf = '../page_list.jsp'"/>
</form>
<!-- 値段管理リストの表示 -->
登録した値段件数:<%= combined.getDataNum()%>
<table border="1">
<!-- 属性名 -->
<tr>
<th><p>値段</p></th>
<th><p>商品名</p></th>
<th><p>店名</p></th>
<th><p>登録日</p></th>
</tr>
<!-- 値段管理リストデータを埋め込む-->
<% for (int i = 0; i < combined.getDataNum(); i++) {//データ数だけ表示させる
%>
<tr>
<td><%=combined.getPrice(i)%>円</td><!-- 値段 -->
<td><%=combined.getMerchandiseName(i)%></td><!-- 商品名 -->
<td><%=combined.getShopName(i)%></td><!-- 店名 -->
<td><%=combined.getCreatedAt(i)%></td><!-- 登録日 -->
</tr>
<%}%>
</table>
</div>
</body>
</html>
Model:Java
店データを取得
- 店ID
- 店名
コードの詳細(クリックすると表示されます)
import java.sql.*;
/**
*
* @author yuya0
*/
public class ShopDb {
/* フィールドの定義 */
protected int[] shopId = new int[10];//店UD
protected String[] shopName = new String[10];//店名
protected Date[] createdAt = new Date[10];//登録日
protected int dataNum;//データ取得件数
/**
* 店データ取得メソッド
*
* @throws Exception
*/
public void dataload() throws Exception {
/* データベースに接続 */
dataNum = 0;
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/kadai15?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url, "softd", "yuya4649");
/* SELECT文の実行 */
String sql = "SELECT *FROM shop";
PreparedStatement stmt = conn.prepareStatement(sql);//JDBCのステートメント(sql)を作成
ResultSet resultSet = stmt.executeQuery();//ステートメントを実行しリザルトセットに代入
/* 結果の取り出しと表示 */
while (resultSet.next()) {
this.shopId[dataNum] = resultSet.getInt("shop_id");
this.shopName[dataNum] = resultSet.getString("shop_name");
this.createdAt[dataNum] = resultSet.getDate("created_at");
dataNum++;
}
/* データベースからの切断 */
resultSet.close();
stmt.close();
conn.close();
}
/**
*店名を登録するメソッド
* @param registerShopName//登録する店名
* @throws Exception
*/
public void insert(String registerShopName) throws Exception{
/* データベースに接続 */
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url ="jdbc:mysql://localhost/kadai15?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url,"softd","yuya4649");
/* INSERT文の実行 */
String sql = "INSERT INTO shop (shop_name,created_at) VALUE(?,curDate())";
/* SQL文の設定 */
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, registerShopName);//1つ目の?に引数をセット
/* 実行 */
stmt.executeUpdate();
/* データベースからの切断 */
stmt.close();
conn.close();
}
/* GETアクセッサ */
public int getShopId(int i) {
if (i >= 0 && dataNum > i) {
return shopId[i];
} else {
return 0;
}
}
public String getShopName(int i) {
if (i >= 0 && dataNum > i) {
return shopName[i];
} else {
return null;
}
}
public Date getCreatedAt(int i) {
if (i >= 0 && dataNum > i) {
return createdAt[i];
} else {
return null;
}
}
public int getDataNum() {
return dataNum;
}
}
商品データを取得
- 商品Id
- 商品名
コードの詳細(クリックすると表示されます)
import java.sql.*;
/**
*
* @author yuya0
*/
public class MerchandiseDb {
/* フィールドの定義 */
protected int[] merchandiseId = new int[10];//商品ID
protected String[] merchandiseName = new String[10];//商品名
protected Date[] createdAt = new Date[10];//登録日
protected int dataNum;//データ取得件数
/**
* 商品データ取得メソッド
*
* @throws Exception
*/
public void dataload() throws Exception {
/* データベースに接続 */
dataNum = 0;
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/kadai15?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url, "softd", "yuya4649");//上記URL設定でユーザ名とパスワードを使って接続
/* SELECT文の実行 */
String sql = "SELECT *FROM merchandise";
PreparedStatement stmt = conn.prepareStatement(sql);//JDBCのステートメント(sql)を作成
ResultSet resultSet = stmt.executeQuery();//ステートメントを実行しリザルトセットに代入
/* 結果の取り出しと表示 */
while (resultSet.next()) {
this.merchandiseId[dataNum] = resultSet.getInt("merchandise_id");
this.merchandiseName[dataNum] = resultSet.getString("merchandise_name");
this.createdAt[dataNum] = resultSet.getDate("created_at");
dataNum++;
}
/* データベースからの切断 */
resultSet.close();
stmt.close();
conn.close();
}
public void insert(String registerMerchandiseName) throws Exception {
/* データベースに接続 */
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/kadai15?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url, "softd", "yuya4649");
/* INSERT文の実行 */
String sql = "INSERT INTO merchandise (merchandise_name,created_at) VALUE (?,curDate())";
/* SQL文の設定 */
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, registerMerchandiseName);//1つ目の?に引数をセット
/* 実行 */
stmt.executeUpdate();
/* データベースからの切断 */
stmt.close();
conn.close();
}
/* GETアクセッサ */
public int getMerchandiseId(int i) {
if (i >= 0 && dataNum > i) {
return merchandiseId[i];
} else {
return 0;
}
}
public String getMerchandiseName(int i) {
if (i >= 0 && dataNum > i) {
return merchandiseName[i];
} else {
return null;
}
}
public Date getCreatedAt(int i) {
if (i >= 0 && dataNum > i) {
return createdAt[i];
} else {
return null;
}
}
public int getDataNum() {
return dataNum;
}
}
それぞれのテーブルを結合してデータを取得
- 管理ID
- 値段
- 商品名
- 店名
- 登録日
コードの詳細(クリックすると表示されます)
import java.sql.*;
/**
*
* @author yuya0
*/
public class ConbinedPriceDb {
/* フィールドの定義 */
protected int[] managementId = new int[10];//管理ID
protected int[] price = new int[10];//値段
protected String[] merchandiseName = new String[10];//商品名
protected String[] shopName = new String[10];//店名
protected Date[] createdAt = new Date[10];//値段の登録日
protected int dataNum;//データ数
protected int i;
//データ更新メソッド
public void dataLoad() throws Exception {
/* データベースに接続 */
dataNum = 0;
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost/kadai15?characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection(url, "softd", "yuya4649");
/*SELECT分の実行*/
String sql = "SELECT "
+ "price.management_id,"//管理ID
+ "price.price,"//値段
+ "merchandise.merchandise_name,"//商品名
+ "shop.shop_name,"//店名
+ "price.created_at "//値段の登録日
+ "FROM price "
+ "INNER JOIN merchandise "
+ "ON price.merchandise_id = merchandise.merchandise_id "//merchandiseテーブルから商品名を抽出
+ "INNER JOIN shop "
+ "ON price.shop_id = shop.shop_id ";//shopテーブルから店名を抽出
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet resultSet = stmt.executeQuery();
/* 結果の取り出しと表示 */
while (resultSet.next()) {
this.managementId[dataNum] = resultSet.getInt("management_id");
this.price[dataNum] = resultSet.getInt("price");
this.merchandiseName[dataNum] = resultSet.getString("merchandise_name");
this.shopName[dataNum] = resultSet.getString("shop_name");
this.createdAt[dataNum] = resultSet.getDate("created_at");
dataNum++;
}
/* データベースからの切断 */
resultSet.close();
stmt.close();
conn.close();
}
/* GETアクセッサ */
// 管理IDGETメソッド
public int getManagementId(int i) {
if (i >= 0 && dataNum > i) {
return managementId[i];
} else {
return 0;
}
}
// 値段GETメソッド
public int getPrice(int i) {
if (i >= 0 && dataNum > i) {
return price[i];
} else {
return 0;
}
}
// 商品名GETメソッド
public String getMerchandiseName(int i) {
if (i >= 0 && dataNum > i) {
return merchandiseName[i];
} else {
return null;
}
}
// 店名GETメソッド
public String getShopName(int i) {
if (i >= 0 && dataNum > i) {
return shopName[i];
} else {
return null;
}
}
// 値段の登録日GETメソッド
public Date getCreatedAt(int i) {
if (i >= 0 && dataNum > i) {
return createdAt[i];
} else {
return null;
}
}
// データ数GETメソッド
public int getDataNum() {
return dataNum;
}
}
Controller:Servlet
登録ボタンを押した後のデータの処理
コードの詳細(クリックすると表示されます)
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author yuya0
*/
public class RegisterPriceSer extends HttpServlet {
/*フィールドの定義*/
private int price;//値段
private int merchandiseId;//商品ID
private int shopId;//店ID
private final PriceDb registerPrice = new PriceDb();//値段テーブルのインスタンスを宣言
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @param errorMessage
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response, String[] errorMessage)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try ( PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>エラー</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>入力に誤りがあります</h1>");
//エラーを表示させる
for(int i = 0; errorMessage[i]!=null; i++){
out.println("<p>"+errorMessage[i]+"</p>");
}
out.println("</body>");
out.println("</html>");
}
}
/*
* doPostメソッド
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//文字コード等 基本設定
response.setContentType("text/html; charset=UTF-8");
request.setCharacterEncoding("UTF-8");
//値段管理リストから受け取ったデータをそれぞれの変数に取得
price = Integer.parseInt(request.getParameter("register_price"));
merchandiseId = Integer.parseInt(request.getParameter("register_merchandise_id"));
shopId = Integer.parseInt(request.getParameter("register_shop_id"));
//エラーを格納する変数
String[] errorMessage = new String[3];
int i = 0;
try {
if (price <= 0) {//価格が0以上だとエラーメッセージが格納される
errorMessage[i] = "値段は0円以上です";
i++;
}
if (merchandiseId == -1) {//商品が未選択だと-1が代入され、エラーメッセージが格納される
errorMessage[i] = "商品を選んで下さい";
i++;
}
if (shopId == -1) {//店が未選択だと-1が代入され、エラーメッセージが格納される
errorMessage[i] = "店を選んで下さい";
i++;
}
if (i==0) {//エラーメッセージが一つも格納されていない場合は、正常にデータベースに登録される
//値段テーブルに登録
registerPrice.insert(price,merchandiseId,shopId);
//値段管理リストに遷移
response.sendRedirect("/Web/final/price_list/price_list_page_db_connection.jsp");
}else{
processRequest(request,response,errorMessage);//エラー画面に遷移
}
} catch (Exception e) {
processRequest(request, response, null);//エラー表示
}
}
}
終わりに
今回はMVCモデルの学習を授業を通して学び、備忘録として残しました。これから、Androidアプリ開発においてMVVMモデルを学ぶので、個人的にはMVCモデルを知っておいて良かったなと感じました。
最後まで読んでいただき、ありがとうございました!