# JDBC個人開発演習 ## 要件定義 | 工程 | ドキュメント | 内容 | | ---- | ---- | ---- | | 要件定義 | 要件定義 | 成果物:運動管理システム | ||| ターゲット層:10~20歳の男女 | ||| 東京都に住むダイエットの進捗で悩む高校2年生の男性 | ||| システムの目的:自分の運動進捗を可視化 | ||| メリット:見える化することでモチベーションアップ | ||| 機能:個人毎の運動内容を表示 | ||| 実装手段:Java13、Mysql8.0、XAMPP | <br></br> ## 基本設計 | 工程 | ドキュメント | 内容 | | ---- | ---- | ---- | | 基本設計 | 基本設計 | フローチャート作成 | ||| テーブル定義 | ||| ER図 | ||| PG | ||| test | <br></br> ## スケジュール ![](https://i.imgur.com/uGliZCJ.png) <br></br> ## ファイル構造 都合上JDBCとchart.jsは分けています ### JDBC >motion/  ├ UserTableDao.java  ├ MotionTableDao.java  ├ DaoCon.java  │  └ main.java <br></br> ### Chart.js > XAMPP/   └ htdocs/     └ htdocs/       ├ chart.php       └ funcs.php <br></br> ![](https://i.imgur.com/qYPFqxj.png) <br></br> ## DB設計 ### DB定義 > ***DB*** >> **motion** ```mysql # mysql -u root -p CREATE DATABASE motion; GRANT ALL ON motion. * TO 'seed'@'localhost'; ``` <br></br> ### TABLE定義 > **user_table** >> user_id >> user_name >> user_old ```mysql # mysql -u seed -p # use motion; CREATE TABLE user_table( user_id INT not null, user_name VARCHAR(15) not null, user_old INT not null ); alter table user_table add primary key (user_id); alter table user_table add unique (user_id, user_name); ``` <br></br> > **motion_table** >> user_id >> motion_id >> motion_name >> motion_details ```mysql CREATE TABLE motion_table( user_id INT not null, motion_id INT not null, motion_name VARCHAR(10) not null, motion_day VARCHAR(20) not null, motion_details VARCHAR(10) not null ); ALTER TABLE motion_table add primary key (user_id, motion_id); ALTER TABLE motion_table add unique (motion_id, motion_name); ALTER TABLE motion_table ALTER motion_id SET DEFAULT 1; ALTER TABLE motion_table ALTER motion_name SET DEFAULT "ランニング"; #変更点 ALTER TABLE motion_table MODIFY motion_details int NOT NULL; #確認 show columns from motion_table; ``` ### ER図 ![](https://i.imgur.com/BhsTSEr.png) ## Java | 動作環境 | ツール | 機能 | | ---- | ---- | ---- | | Java | eclipse | DBをコマンドを使わず操作できる | ### Main > ここではDAOで記述されたメゾットを呼び出し実行するfileです。 ユーザー情報の追加、変更、削除を行うことができます。 <details><summary><span style="color: red; ">Main.java</span></summary><div> ```java= package motion; import java.util.Scanner; public class Main { public static void main(String[] args) { new DaoCon(); Scanner scanner = new Scanner(System.in); System.out.println("処理を選択してください"); System.out.printf("1.ユーザ情報"); System.out.println("2.成績"); System.out.printf("入力>>>"); int n = scanner.nextInt(); if (n == 1) { System.out.println("1 ユーザー情報を変更します"); System.out.println("2 ユーザー情報を作成します"); System.out.println("3 ユーザー情報を削除します"); System.out.printf("入力>>>"); int inputNum1 = scanner.nextInt(); switch (inputNum1) { case 1: //ユーザ情報の変更 UserTableDao.UserTableUpdate(); break; case 2: //新規ユーザ情報の追加 UserTableDao.UserTableInsert(); break; case 3: //ユーザ情報の削除 UserTableDao.UserTableDelete(); break; } } else if (n == 2) { System.out.println("1 成績を修正します"); System.out.println("2 成績を登録します"); System.out.println("3 成績を表示します"); System.out.printf("入力>>>"); int inputNum2 = scanner.nextInt(); switch (inputNum2) { case 1: //成績の変更 MotionTableDao.MotionTableUpdate(); break; case 2: //成績の追加 MotionTableDao.MotionTableInsert(); break; case 3: //成績の表示 MotionTableDao.MotionTableSELECT(); break; } } else { System.out.println("1か2を入力してください"); } } } ``` </div></details> ### DaoConstructor > Daoで使用される定数を格納しています。 <details><summary><span style="color: red; ">DaoCon.java</span></summary><div> ```java= package motion; public class DaoCon extends Main { //user_table Integer user_id; String user_name; Integer user_old; //motion_table Integer motion_id; String motion_name; String motion_day; Integer motion_details; } ``` </div></details> ### UserTableDao > データベースを操作する為の各メゾットが格納されています。 <details><summary><span style="color: red; ">UserTableDao.java</span></summary><div> ```java= package motion; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Scanner; public class UserTableDao { //DELETE public static void UserTableDelete() { System.out.println("<WARNING>"); Scanner scanner = new Scanner(System.in); System.out.printf("削除するIDを選択>>>"); int inputId = scanner.nextInt(); System.out.printf("本当に削除しますか?: Y/n >>>"); char inputYN = scanner.next().charAt(0); try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); if (inputYN == 'Y') { String sql = "DELETE FROM user_table WHERE user_id = ?;"; PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(1, inputId); stmt.executeUpdate(); stmt.close(); con.close(); } else { System.out.println("削除しませんでした"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //INSERT public static void UserTableInsert() { Scanner scanner = new Scanner(System.in); System.out.printf("作成IDを入力>>>"); int inputId = scanner.nextInt(); System.out.printf("名前を入力>>>"); String inputName = scanner.next(); System.out.printf("年齢を入力>>>"); int inputOld = scanner.nextInt(); try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); String sql = "INSERT INTO user_table VALUES(?,?,?)"; PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(1, inputId); stmt.setString(2, inputName); stmt.setInt(3, inputOld); stmt.executeUpdate(); stmt.close(); con.close(); scanner.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //UPDATE public static void UserTableUpdate() { try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); Scanner scanner = new Scanner(System.in); System.out.printf("変更するIDを入力してください >>>"); int inputId = scanner.nextInt(); System.out.printf("変更する名前を入力してください >>>"); String inputName = scanner.next(); System.out.println("年齢は変更できません 管理者にお問い合わせください"); System.out.printf("本当に変更しますか?: Y/n >>>"); char inputYN = scanner.next().charAt(0); if (inputYN == 'Y') { String sql = "UPDATE user_table SET user_name = ? WHERE user_id = ?;"; PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(2, inputId); stmt.setString(1, inputName); stmt.executeUpdate(); stmt.close(); con.close(); } else { System.out.println("変更しませんでした"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } ``` </div></details> ### MotionTableDao > 運動情報の備考の記載、過去データを見ることができるメゾットが格納されています。 JDBC上でSELECT使うの地獄すぎ <details><summary><span style="color: red; ">MotionTableDao.java</span></summary><div> ```java= package motion; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner; public class MotionTableDao { //SELECT public static void MotionTableSELECT() { try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); String sql = "SELECT * FROM motion_table"; Statement stmt = con.createStatement(); PreparedStatement ps = con.prepareStatement(sql); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { int u_id = rs.getInt("user_id"); int m_id = rs.getInt("motion_id"); String name = rs.getString("motion_name"); String day = rs.getString("motion_day"); int details = rs.getInt("motion_details"); System.out.println(u_id + "\t" + m_id + "\t" + name + "\t" + day + "\t" + details); } rs.close(); stmt.close(); con.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //INSERT public static void MotionTableInsert() { Scanner scanner = new Scanner(System.in); System.out.printf("UserIDを入力>>>"); int inputId = scanner.nextInt(); System.out.printf("日付を入力>>>"); String inputDay = scanner.next(); System.out.printf("備考を入力>>>"); int inputDetails = scanner.nextInt(); try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); String sql = "INSERT INTO motion_table VALUES(?,?,?,?,?)"; PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(1, inputId); stmt.setInt(2, 1); stmt.setString(3, "ランニング"); stmt.setString(4, inputDay); stmt.setInt(5, inputDetails); stmt.executeUpdate(); stmt.close(); con.close(); scanner.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } //UPDATE public static void MotionTableUpdate() { try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection con = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/motion", "seed", "Tech_123"); Scanner scanner = new Scanner(System.in); System.out.printf("変更するIDを入力してください >>>"); int inputId = scanner.nextInt(); System.out.printf("備考を入力してください >>>"); int inputDetailes = scanner.nextInt(); System.out.printf("本当に変更しますか?: Y/n >>>"); char inputYN = scanner.next().charAt(0); if (inputYN == 'Y') { String sql = "UPDATE motion_table SET motion_details = ? WHERE user_id = ?;"; PreparedStatement stmt = con.prepareStatement(sql); stmt.setInt(2, inputId); stmt.setInt(1, inputDetailes); stmt.executeUpdate(); stmt.close(); con.close(); } else { System.out.println("変更しませんでした"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } ``` </div></details> <br></br> ## Chart.js > コンソール画面だけでは味気ないので**データ可視化**というテーマに着目し、localhost上でデータベースをグラフ化し表示するものを作成した。 | 動作環境 | ツール | 機能 | | ---- | ---- | ---- | | php | XAMPP | DBをグラフ化することで直観的にデータを見れる | ### func > DBを呼び出している <details><summary><span style="color: red; ">func.php</span></summary><div> ```php= <?php function db_connect(){ try { $pdo = new PDO('mysql:dbname=motion;charset=utf8;host=localhost','seed','Tech_123'); } catch (PDOException $e) { exit('DBConnectError:'.$e->getMessage()); } return $pdo; } ?> ``` </div></details> ### chart > DBをグラフ化している > ここではscpriptの部分で直接chart.jsを呼び出している <details><summary><span style="color: red; ">chart.php</span></summary><div> ```php= <?php include('funcs.php'); $pdo = db_connect(); $motion_name = ''; $motion_details = ''; $stmt = $pdo->prepare("SELECT* FROM motion_table"); $status = $stmt->execute(); while( $r = $stmt->fetch(PDO::FETCH_ASSOC)){ $motion_name = $motion_name . '"'. $r['motion_name'].'",'; $motion_details = $motion_details . '"'. $r['motion_details'] .'",'; } $motion_name = trim($motion_name,","); $motion_details = trim($motion_details,","); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>成績</title> </head> <body> <canvas id="myChart" width="400" height="400"></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script> <script> var ctx = document.getElementById('myChart').getContext('2d'); var myChart = new Chart(ctx, { type: 'bar', data: { labels: [<?php echo $motion_name ?>],//各棒の名前(name) datasets: [{ label: '# 距離(km)', data: [<?php echo $motion_details ?>],//各縦棒の高さ backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { scales: { yAxes: [{ ticks: { beginAtZero: true } }] } } }); </script> </body> </html> ``` </div></details> ### 現状の成果物 秘密