# Java-DB連携演習課題
## はじめに(演習の⽬的と取り組み⽅)
当演習は、講義で学んだことを⾃⼒で実践できるようになるために実施します。 そのために以下の内容を守って演習に取り組んでください。
### 納品物、納期を守りましょう
この演習は、実際の仕事を想定した内容です。
提出物の内容と提出期限は必ず守ってください。
作業が間に合わない、提出物に問題が出そうな場合は、**必ずルールにしたがって適切な相⼿に相談してください**。
### 適切な⼿順で開発しましょう
プログラムを書き始める前に、**README.md** や**仕様書**(配布されている場合) を必ず読んでください。
「**何を作るのか**」、「**どこまで作ればよいのか**」を理解してから作業を始めてください。
### 知らないことは⾃分で調べましょう
この演習には、**講義で扱っていない内容が⼀部含まれています**。
その場合は、インターネットなどで⾃分で調べながら進めてください。
調べることも、エンジニアにとって⼤切なスキルの⼀つです。
## **各種説明**
### **Eclipseでの「README.md」表示方法**
* Eclipseのテキストエディタウィンドウ上に、「README.md」ファイルをドラッグアンドドロップする
* プロジェクトに「README.md」がある場合はダブルクリックする
### **演習目的**
DAOとDTOというデザインパターンを取り入れた、JavaとDBを連携させるシステムの開発演習です。
学習した知識のアウトプット、デザインパターンの活用法の学習として実施していただきます。
また、課題をとおして以下のようなビジネススキルも合わせて学習していただきます。
* 納期の重要さ
* 開発の進め方
* 調査力
* 質問力
### **システム名**
社員メンテナンス
### **システム説明**
社員情報(employeeテーブル)のCRUDシステム
* ※CRUDとは
Create(生成)、Read(読み取り)、Update(更新)、Delete(削除)の機能を有したシステムのこと。
### **配布物**
* 実行例フォルダ
* srcフォルダ
【修正対象】
* com.rhizome.example.main.Main.java
* com.rhizome.example.util.DbUtil.java
* com.rhizome.example.dao.EmployeeDAO.java
* sqlフォルダ(既に講義で配布済みなら不要)
### **納品物**
作成したプログラム
### **共通事項**
* 例外はmain()メソッドまでスローし、main()メソッドでキャッチする
例外処理はprintStackTrace()メソッドを使用するだけでOK(実際はもっと考える必要があります)
* DBとの連携は「PreparedStatement」を使用すること
### **進め方**
1. 各種説明をじっくり読んで把握しましょう
把握できなければ質問してください。
2. プロジェクトにどのようなファイルがあるかをすべて確認してください
3. 確認できたら、1段階目から順に進めてください
4. 配布物に書いてある、修正対象のクラスを修正、もしくは新規クラスを追加して作成してください
※指示以外でも、適宜クラスやメソッドを分けて作成していただいても問題ありません。
### **ゴール**
この問題を解き終わったら、DBを使用した社員のCRUDシステムが完成します。
問題を通して、以下のことができるようになることがゴールです。
すべて身につけられた方は素晴らしいです。
もちろんすべては難しくても、いくつかは達成できるように取り組みましょう。
* JavaからDBへの接続方法を確認し実装できるようにする
* PreparedStatementを使ってSQLを実行できるようにする
* DAOとDTOの意味・メリットを知って使い方を理解する
---------------------------------------
## **問題**
#### 1段階目(DB接続処理作成→全検索完成)
Main.javaとEmployeeDAOで出ているエラーを無くしましょう。
DbUtilクラスにDBへの接続と切断系のメソッド定義を追加します。
**<作成フローとポイント>**
1. DbUtilクラスの修正
1. DB接続用メソッドを作成する
| メソッド名 | getConnection |
| 戻り値の型 | Connection |
| 引数リスト | なし |
| 処理内容 | Connectionを生成し、それを戻す |
* 既存の定数を活用しましょう
* Connectionは生成したら、用意されたフィールドに代入しましょう
* Mainクラスからの呼び出し方が「クラス名.メソッド名」となっていることに注意してください
* 必須ではないですが、Connectionが「nullではなくかつ接続状態である」場合は、
生成せずにフィールドをreturnするという処理にすると、無駄に生成しないためさらによい処理になります
(切断されているかどうか調べるメソッドがあります)
2. PreparedStatementクローズ用メソッドを作成する
| メソッド名 | closeStatement |
| 戻り値の型 | なし |
| 引数リスト | クローズするプリペアドステートメント(PreparedStatement型) |
| 処理内容 | 引数がnullではなかったら、PreparedStatementを切断する |
* 切断系メソッドはnullが引数として渡される可能性があるためnullチェックを入れましょう
* PreparedStatementの切断用メソッドは調査してみましょう
* 切断系メソッドもMainクラスからの呼び出し方が「クラス名.メソッド名」となっていることに注意してください
3. DB切断用メソッドを作成する
| メソッド名 | closeConnection |
| 戻り値の型 | なし |
| 引数リスト | 切断するコネクション(Connection型) |
| 処理内容 | 引数がnullではなかったら、Connectionを切断する |
* No.2と同様のフローで作成しましょう
* Connectionの切断用メソッドは調査してみましょう
上記が完成すると、全検索が実行可能になります。
**<実行例>** Main.javaを実行
```
システムを開始します
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
1 ←1を入力
山田龍也
高橋準
麻枝史明
丸戸章介
三宅武
丸井悠
涼元香織
葉山稔
川上朱里
杉井肇
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
※名前の一覧が検索できます
#### 2段階目(名前検索から全データ検索に)
名前だけの表示から、全カラム表示に変更しましょう。
その際に必要なのがDTOです。
メソッドの戻り値は【1つのデータ】しか返却できません。
全カラムデータを返却するには、DTOを使うとよいです。
**<作成フローとポイント>**
1. EmployeeDTOクラスの作成
1. com.rhizome.example.dtoパッケージを作成し、そこに「EmployeeDTO.java」クラスを追加する
2. EmployeeDTOにEmployeeテーブルのカラム分のフィールドをすべてprivateで宣言する
フィールド名や型の参考先:「sql/DAO作成用テーブル定義書.xlsx」
3. EmployeeDTOに各フィールドのgetter/setterを用意する
Eclipseの機能を使うと楽に作成できます(わからなければ調査しましょう)
2. EmployeeDAOクラスの修正
1. EmployeeDAOのselectAll()メソッドにて、戻り値のジェネリクス(<データ型>)部分を「String」→「EmployeeDTO」に変更する
2. SQL実行結果取得処理のwhile文の中でEmployeeDTOのインスタンスを生成し、DBから取得した各カラムのデータをすべてDTOにセット後、EmployeeDTOをリストに追加する
3. Mainクラスの修正
1. Main.javaのempSelect()メソッドのエラーを修正する
* 戻り値の型に気を付けましょう
* 表示する処理はメソッド化すると楽になります
**<実行例>** Main.javaを実行
```
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
1 ←1を入力
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
10002 麻枝史明 マエダフミアキ fmak@hoge.jp ccc 11
10003 丸戸章介 マルトショウスケ marusyo@hoge.jp ddd 12
10004 三宅武 ミヤケタケシ miya@hoge.jp eee 13
10005 丸井悠 マルイハルカ haru@hoge.jp fff 13
10006 涼元香織 スズモトカオリ suzumoto@hoge.jp ggg 13
10007 葉山稔 ハヤマミノル mhayama@hoge.jp hhh 14
10008 川上朱里 カワカミアカリ kawakami@hoge.jp iii 14
10009 杉井肇 スギイハジメ sugi@hoge.jp jjj 15
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
#### 3段階目(DAOのIDによる検索メソッドを作成→条件検索完成)
条件検索用のメソッドをDAOに追加し、
条件検索が選択された際の処理を完成させましょう。
上記が完成すると、条件検索が実行可能になります。
**<作成フローとポイント>**
1. EmployeeDAOクラスの修正
EmployeeDAOクラスにselectById()メソッドを作成する(既存のselectAll()メソッドを参考にしましょう)
| メソッド名 | selectById |
| 戻り値の型 | DTOのリスト(List) |
| 引数リスト | 社員ID(int型) |
| 処理内容 | 社員テーブルから指定された社員IDに一致するデータを取得し、DTOに設定の上、リスト形式で戻す |
2. Mainクラスの修正
Mainクラスで「1」(検索)→「2」(条件検索)が入力された場合の処理を作成しましょう
* 以下の実行例と同じ動作になるように実装してください
* selectById()メソッドを利用して検索結果を取得しましょう
* 指定されたIDに一致するデータのみを画面に表示しましょう
* 値の入力にはMainクラスに用意されているinputCheck()メソッドを活用しましょう(以降すべて)
**<実行例>** Main.javaを実行
```
システムを開始します
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
2
IDを入力してください
10010 ←存在しないIDを入力
入力された値で情報がみつかりませんでした
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
2
IDを入力してください
10001
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
#### 4段階目(DAOのデータ削除メソッドを作成→削除処理完成)
削除用のメソッドをDAOに追加し、
削除が選択された際の処理を完成させましょう。
**<作成フローとポイント>**
1. EmployeeDAOクラスの修正
EmployeeDAOクラスにempDelete()メソッドを作成しましょう
| メソッド名 | empDelete |
| 戻り値の型 | なし |
| 引数リスト | 社員ID(int型) |
| 処理内容 | 社員テーブルから指定された社員IDに一致するデータを削除する |
2. Mainクラスの修正
Mainクラスでは「4」(削除)を入力した時の処理を作成しましょう
* 以下の実行例と同じ動作になるように実装してください
* IDは数値のみ入力できるようにしましょう
* 存在チェックはEmployeeDAOクラスのselectById()メソッドを利用しましょう
* データの削除はEmployeeDAOクラスのempDelete()メソッドを利用しましょう
**<実行例>** Main.javaを実行
```
システムを開始します
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
4
IDを入力してください
99999 ←存在しないIDを入力
入力された値で情報がみつかりませんでした
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
4
IDを入力してください
10002
指定されたIDの情報を削除します? Y/y
(Y/y以外の入力であればキャンセル)
y ←削除を選択
削除が完了しました
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
2
IDを入力してください
10002 ←削除したIDを入力
入力された値で情報がみつかりませんでした
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
#### 5段階目(DAOのデータ登録メソッドを作成→登録処理完成)
登録用のメソッドをDAOに追加し、
登録が選択された際の処理を完成させましょう。
**<作成フローとポイント>**
1. EmployeeDAOクラスの修正
EmployeeDAOクラスにempInsert()メソッドを作成しましょう
| メソッド名 | empInsert |
| 戻り値の型 | なし |
| 引数リスト | 名前(String型),カナ(String型),メール(String型),パスワード(String型),部署ID(int型) |
| 処理内容 | 社員テーブルに指定された情報を新規登録する |
2. Mainクラスの修正
Mainクラスでは「2」(登録)を入力した時の処理を作成しましょう
* 以下の実行例と同じ動作になるように実装してください
* 部署IDは数値のみ入力できるようにしましょう
* データの追加はEmployeeDAOクラスのempInsert()メソッドを利用しましょう
**<実行例>** Main.javaを実行
```
システムを開始します
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
2
社員名を入力してください
てすと
フリガナを入力してください
テスト
メールアドレスを入力してください
test@hoge.jp
パスワードを入力してください
xxx
部署IDを入力してください
12
登録が完了しました
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
1 ←1を入力
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
10002 麻枝史明 マエダフミアキ fmak@hoge.jp ccc 11
10003 丸戸章介 マルトショウスケ marusyo@hoge.jp ddd 12
10004 三宅武 ミヤケタケシ miya@hoge.jp eee 13
10005 丸井悠 マルイハルカ haru@hoge.jp fff 13
10006 涼元香織 スズモトカオリ suzumoto@hoge.jp ggg 13
10007 葉山稔 ハヤマミノル mhayama@hoge.jp hhh 14
10008 川上朱里 カワカミアカリ kawakami@hoge.jp iii 14
10009 杉井肇 スギイハジメ sugi@hoge.jp jjj 15
10010 てすと テスト test@hoge.jp xxx 12 ←入力したデータが追加されている
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
#### 6段階目(DAOのデータ更新メソッドを作成→更新処理完成)
更新用のメソッドをDAOに追加し、
更新が選択された際の処理を完成させましょう。
**<作成フローとポイント>**
1. EmployeeDAOクラスの修正
EmployeeDAO.javaにempUpdate()メソッド作成しましょう
| メソッド名 | empUpdate |
| 戻り値の型 | なし |
| 引数リスト | 社員ID(int型),名前(String型),カナ(String型),メール(String型),パスワード(String型),部署ID(int型) |
| 処理内容 | 社員テーブルの指定された社員IDに一致するデータを引数の内容に更新する |
2. Mainクラスの修正
Mainクラスでは「3」(更新)を入力した時の処理を作成しましょう
* 以下の実行例と同じ動作になるように実装してください
* IDと部署IDは数値のみ入力できるようにしましょう
* 存在チェックはEmployeeDAOクラスのselectById()メソッドを利用しましょう
* データの更新はEmployeeDAOクラスのempUpdate()メソッドを利用しましょう
**<実行例>** Main.javaを実行
```
システムを開始します
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
3
IDを入力してください
10020 ←存在しないIDを入力
入力された値で情報がみつかりませんでした
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
3
IDを入力してください
10010
社員名を入力してください
試し
フリガナを入力してください
タメシ
メールアドレスを入力してください
tameshi@hoge.jp
パスワードを入力してください
yyy
部署IDを入力してください
14
更新が完了しました
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
1
1:全検索 2:条件検索 それ以外:戻る
1 ←1を入力
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
10002 麻枝史明 マエダフミアキ fmak@hoge.jp ccc 11
10003 丸戸章介 マルトショウスケ marusyo@hoge.jp ddd 12
10004 三宅武 ミヤケタケシ miya@hoge.jp eee 13
10005 丸井悠 マルイハルカ haru@hoge.jp fff 13
10006 涼元香織 スズモトカオリ suzumoto@hoge.jp ggg 13
10007 葉山稔 ハヤマミノル mhayama@hoge.jp hhh 14
10008 川上朱里 カワカミアカリ kawakami@hoge.jp iii 14
10009 杉井肇 スギイハジメ sugi@hoge.jp jjj 15
10010 試し タメシ tameshi@hoge.jp yyy 14 ←入力したデータに更新されている
現在のメンテナンス対象テーブル:社員テーブル
1:検索 2:登録 3:更新 4:削除 9:テーブル切替 0:終了
```
***
**<以下、時間が余った人向け>**
#### 7段階目(部署マスター管理作成)
EmployeeDAO、EmployeeDTOを参考にDepartmentDAO、DepartmentDTOを作成し、
部署マスターで全検索、条件検索、削除、登録、変更を実装する。
また、9テーブル切替を行うたびに社員と部署のテーブルを切り替える。
#### 8段階目(機能改善)
* 社員テーブルの検索時、部署IDの代わりに部署名を表示する
* 社員テーブルの全検索時、縦の線が揃うように位置を調整する
* 社員テーブルの更新時、変更したくない項目は何も入力せずにEnterを押せるようにする
* 社員テーブルの登録・更新時、存在しない部署IDを入力するとエラーになるようにする
* 社員テーブル、部署テーブル共に登録・変更時はSQL実行前に登録・変更を行ってよいか確認させる
#### 9段階目(検索機能改善)
* 社員テーブル、部署テーブル共に条件検索時はID以外の項目でも検索できるようにする
* 検索条件の中で社員名、フリガナ、メールアドレス、部署名は曖昧検索できるようにする
* 社員テーブルの条件検索ではAND条件で複数の項目を指定することができるようにする
#### 10段階目(部署入力改善)
* 社員テーブルの登録・更新時、部署はIDでも部署名でも入力できるようにする
部署名で入力した場合は部署名の一部でも特定できればOKとする(例:「総務」と入力)
以上