【初心者向け/ITスクール34日】JDBCを通してMVCパターンを具象する方法
はじめに
今日は、ITスクールに通った34日目の日で、今日学んだ知識を記事にシェアしたいと思います。本記事が、ITを勉強を始めた方々にもロードマップになればいいと思います。
34日目は、JDBCを通して、Oracle DBMSに繋ぎ、Javaを通してMVCパターンを具象する実習をしました。自由課題として、先生からヒントなしという予告がありましたので、直接実践でまず経験してみました。
一つの機能を作成することは大丈夫でしたが、それは構造化してまとめることがとても難しかったです。例えば、Connectionはどこで配置するか、Scannerはどこに配置するかのように、Classの役割を決めることはとても難しかったと思います。
以前、ダウンロードをした画像になりますが、URLを忘れました
、
MはMODELとして、DBにデーターを送ったり、もらったりする役割で、ビジネスロジックとデーターを扱うアプリケーションです。クライアントには目に見えない領域で、
いわゆるCRUDを担当します。DAOを通して具象しました。
VはVIEWとして、コンソール(本来ならhtml)になり、入力と結果の出力を担当します。クライアントにメイル画面だと考えば分かりやすいです。
CはControllerとして、直接つながらいMとVの架け橋みたいなものだと捉えたらいいと思います。
1.DB作成
まずはVとMを通してデーターを交換するためには、まずデーターをもらう器が必要になります。
DBをそのようあ役割です。
やはり、DMLよりはDDL、性格にモデリングがとても難しいと痛感しました。
CREATE TABLE TORIKIZOKU(
t_location VARCHAR2(20 CHAR) PRIMARY KEY,
t_name VARCHAR2(10 CHAR) NOT NULL,
t_seat NUMBER(3) NOT NULL
);
CREATE TABLE RESERVATION(
r_no NUMBER(3) PRIMARY KEY,
r_name VARCHAR2(10 CHAR) NOT NULL,
r_time DATE NOT NULL,
r_phonenum VARCHAR2(20 CHAR) NOT NULL,
r_location VARCHAR2(20 CHAR)
);
CREATE SEQUENCE RESERVATION_SEQ;
2.DTO(VO)作成
テーブルはエンティティの集まり、要するにオブジェクトの集まりだとも言えます。
そのため、DTOはテーブルごとに作成します。
//field テーブルの属性名とデータータイプ
//constuructor basic, all fieldsコンストラクタ
//getter setter
Reservationのデーターをjava.util.Dateをimportします。
後ほど、java.sql.Dateに変換します。
3.DB Manager作成
コードを減らすために、Connectionとcloseのみ担当するクラスを作成します。
package com.hyon.db.manager;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class HyonDBManager {
public static Connection getConnection() throws SQLException {
String address = "jdbc:oracle:thin:@localhost:1521:xe"; return DriverManager.getConnection(address, "id", "pw");
}
public static void close(Connection con, PreparedStatement pstmt, ResultSet rs) {
try {
rs.close();
}catch(Exception e){
}try {
pstmt.close();
}catch(Exception e) {
}try {
con.close();
}catch(Exception e) {
}
}
}
4.ConsoleScreen
Consoleの最初メニュおよび最終結果出力メソッド
public static int showMenu(){
Scanner sc = new Scanner(System.in);
System.out.printf("%-23s%-20s%-20s\n", "1. 予約する", "2. 店舗登録", "3. 全体予約確認");
System.out.printf("%-20s%-20s%-20s\n", "4. 全体店舗検索", "5. 店舗検索", "6. 予約検索");
System.out.printf("%-20s%-20s%-20s\n", "7. 予約情報訂正", "8. 予約キャンセル", "9. 終了");
System.out.println();
System.out.print("メニュー番号 : ");
return sc.nextInt();
}
public static void printResult(String result) {
System.out.println(result);
}
main
public class Controller {
public static void main(String[] args) {
int menu;
System.out.println("Torikizoku Program Start!");
while(true) {
try {
menu =ConsoleScreen.showMenu();
if(menu==9) {
System.out.println("bye bye");
System.exit(0);
}
else if(menu==1) {ConsoleScreen.printResult(null);}
else if(menu==2) {ConsoleScreen.printResult(null);}
else if(menu==3) {ConsoleScreen.printResult(null);}
else if(menu==4) {ConsoleScreen.printResult(null);}
else if(menu==5) {ConsoleScreen.printResult(null);}
else if(menu==6) {ConsoleScreen.printResult(null);}
else if(menu==7) {ConsoleScreen.printResult(null);}
else if(menu==8) {ConsoleScreen.printResult(null);}
} catch (Exception e) {
e.printStackTrace();
}
}
}//main
}//class
ViewとControllerの役割をどこからどこまでするかを決められなかったので、進むことができませんでした。
メニュをコンソールに出力し、menunumまで入力するメソッドです。
Controllerをmainにし、menunumからもらった数字によって、違うDAOのメソッドを呼び出す仕組みに設定しました。9番を押せば、終了になるプログラムです。
結局、この仕組みを組めるかどうかによって、進みが変わったと思います。
メニューごとに案内文を出力し、データーを入力するメソッド
基本的な仕組みが出来上がったので、残りはメニューごとにUserが入力してもらうためのメソッドを作成し、それをDTOを媒体に伝えることです。
ですから、このタイミングで入力した値をパラメーターにし、DTOのオブジェクトを生成します。Controllerはあくまでその値をDAOに繋がる役割だけです。
5. CUD
まず、CUDの場合はこの入力してもらったデーターをDTOに込めて、伝える必要がありますので。DTOのオブジェクトを生成します。
//1. 予約情報入力
public static Reservation ShowReserveEnrollMenu() throws ParseException {
Scanner sc = new Scanner(System.in);
System.out.print("予約者名 : ");
String name = sc.next();
System.out.print("予約時間(YYYY-MM-DD/HH:mm) : ");
String when = sc.next();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD/HH:mm");
Date when2 = sdf.parse(when);
System.out.print("携帯番号 : ");
String phoneNum = sc.next();
System.out.print("支店名 : ");
String location = sc.next();
return new Reservation(0, name, when2, phoneNum, location);
}
//2. 店を登録するメソッド-> TorikizokuのDTO
public static Torikizoku showTorikiEnrollMenu(){
Scanner sc = new Scanner(System.in);
System.out.print("支店名 : ");
String location = sc.next();
System.out.print("店長名 : ");
String name = sc.next();
System.out.print("座席数 : ");
int seat = sc.nextInt();
return new Torikizoku(location, name, seat);
}
public static void main(String[] args) {
int menu;
String result;
Torikizoku t = null;
Reservation r = null;
System.out.println("Torikizoku Program Start!");
while(true) {
try {
menu =ConsoleScreen.showMenu();
if(menu==9) {
System.out.println("bye bye");
System.exit(0);
}
else if(menu==1) {
r = ConsoleScreen.ShowReserveEnrollMenu();
result = DAO.insertReservation(r);
ConsoleScreen.printResult(result);
}
else if(menu==2) {
t = ConsoleScreen.showTorikiEnrollMenu();
//result = DAO.method(t)
//ConsoleScreen.printResult(result);
}
//1
public static String insertReservation(Reservation r) {
Connection con = null;
PreparedStatement ptsmt = null;
try {
con = HyonDBManager.getConnection();
String sql="INSERT INTO RESERVATION VALUES"
+ "(RESERVATION_SEQ.NEXTVAL,?,?,?,?)";
ptsmt = con.prepareStatement(sql);
ptsmt.setString(1, r.getName());
ptsmt.setDate(2, new Date(r.getWhen().getTime()));
ptsmt.setString(3, r.getPhoneNum());
ptsmt.setString(4, r.getLocation());
if(ptsmt.executeUpdate()==1) {
return "予約成功";
}
return ""; // java文法上、必修
}catch(Exception e) {
e.printStackTrace();
return "予約失敗";
}finally {
HyonDBManager.close(con, ptsmt, null);
}
}
//2
public static String insertTorikizoku(Torikizoku t) {
Connection con = null;
PreparedStatement ptsmt = null;
try {
con = HyonDBManager.getConnection();
String sql="INSERT INTO TORIKIZOKU VALUES"
+ "(?,?,?)";
ptsmt = con.prepareStatement(sql);
ptsmt.setString(1, t.getLocation());
ptsmt.setString(2, t.getName());
ptsmt.setInt(3, t.getSeat());
if(ptsmt.executeUpdate()==1) {
return "店舗登録成功";
}
return ""; // java文法上、必修
}catch(Exception e) {
return "予約失敗";
}finally {
HyonDBManager.close(con, ptsmt, null);
}
}
のこりは、DAOからデーターを処理し、Stringにリターンすることだけです。
事前に、作ったConsoleScreenから出力したら終わりです。
6. R
データーを読みたい場合は、逆にDAOからDBのデーターをアウトプットし、
Viewからそのデーターを出力します。
DAO
ResultSetからクエリの結果を込め、Iterator、DTOを活用して
ArrayListに込めます。
//3
public static ArrayList<Reservation> selectAllReserve(){
Connection con = null;
PreparedStatement ptsmt = null;
ResultSet rs = null;
try {
con = HyonDBManager.getConnection();
String sql = "SELECT * FROM RESERVATION";
ptsmt = con.prepareStatement(sql);
rs = ptsmt.executeQuery();
ArrayList<Reservation> rlist = new ArrayList<>();
while(rs.next()) {
Reservation r = new Reservation();
r.setNo(rs.getInt("r_no"));
r.setName(rs.getString("r_name"));
r.setWhen(rs.getDate("r_time"));
r.setPhoneNum(rs.getString("r_phonenum"));
r.setLocation(rs.getString("r_location"));
rlist.add(r);
}
return rlist;
}catch(Exception e) {
return null;
}finally {
HyonDBManager.close(con, ptsmt, rs);
}
}
//4
public static ArrayList<Torikizoku> selectAllToriki(){
Connection con = null;
PreparedStatement ptsmt = null;
ResultSet rs = null;
try {
con = HyonDBManager.getConnection();
String sql = "SELECT * FROM TORIKIZOKU";
ptsmt = con.prepareStatement(sql);
rs = ptsmt.executeQuery();
ArrayList<Torikizoku>tlist = new ArrayList<>();
while(rs.next()) {
Torikizoku t = new Torikizoku();
t.setLocation(rs.getString("t_location"));
t.setName(rs.getString("t_name"));
t.setSeat(rs.getInt("t_seat"));
tlist.add(t);
}
return tlist;
} catch (Exception e) {
return null;
}finally {
HyonDBManager.close(con, ptsmt, rs);
}
}
ConsoleScreen
//3
public static void showReserveListResultMenu(ArrayList<Reservation> rlist) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd E a hh:mm");
for (Reservation r : rlist) {
System.out.printf("예약번호:%-3d" , r.getNo());
System.out.printf("예약자명:%-6s " , r.getName());
System.out.printf("예약시간: %-22s" , sdf.format(r.getWhen()));
System.out.printf("핸드폰 번호: %-15s" , r.getPhoneNum());
System.out.printf("지점명: %-6s\n", r.getLocation());
}
}
//4
public static void showTorikiListResultMenu(ArrayList<Torikizoku> tlist) {
for (Torikizoku t : tlist) {
System.out.printf("지점명:%-15s" , t.getLocation());
System.out.printf("지점잠명:%-15s " , t.getName());
System.out.printf("좌석수: %-3d\n" , t.getSeat());
}
}
Discussion