# JDBC個人開発演習
## 要件定義
| 工程 | ドキュメント | 内容 |
| ---- | ---- | ---- |
| 要件定義 | 要件定義 | 成果物:運動管理システム |
||| ターゲット層:10~20歳の男女 |
||| 東京都に住むダイエットの進捗で悩む高校2年生の男性 |
||| システムの目的:自分の運動進捗を可視化 |
||| メリット:見える化することでモチベーションアップ |
||| 機能:個人毎の運動内容を表示 |
||| 実装手段:Java13、Mysql8.0、XAMPP |
<br></br>
## 基本設計
| 工程 | ドキュメント | 内容 |
| ---- | ---- | ---- |
| 基本設計 | 基本設計 | フローチャート作成 |
||| テーブル定義 |
||| ER図 |
||| PG |
||| test |
<br></br>
## スケジュール

<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>

<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図

## 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>
### 現状の成果物
秘密