こんにちは、なかにしです。
現在は業務でJavaとDockerを触ってるので、
前案件のReactを併せて簡易アプリ作ってみようのコーナーです。
リポジトリ
フロントとバックでリポジトリを分けたので、それぞれ乗せときます。
最近はREADMEをちゃんと書くようにしてます。
フロントはこちら
バックはこちら
ざっくりシステム図
システム詳細
①ユーザがボタン押下
②JavaでMySQLからデータ取得、フロントに返却
③受け取ったデータを画面に表示
React側
「ボタン押下時、Java側にリクエストを送り、返ってきたデータを表示する」という処理を書きます。
import { useState } from "react";
import "./App.css";
import axios from "axios";
// 取得データのタイプ
type Data = {
id: number;
name: string;
};
const App = () => {
// データ
const [userData, setUserData] = useState<Data[]>([]);
//データ取得
const getData = () => {
axios
.get("/sample")
.then((response) => {
setUserData(response.data);
})
.catch((e) => {
console.log(e);
});
};
return (
<div className="App">
<h2>データ取得ボタン</h2>
<button onClick={getData}>データ取得</button>
{userData.map((data) => (
<ul key={data.id}>
<li>{data.id}</li>
<li>{data.name}</li>
</ul>
))}
</div>
);
};
export default App;
Java側
Java側はSpring BootというFWで作っています。
IDEはEclipsを使用しています。
▽エンティティ
package com.example.demo.entity;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name="User")
public class User {
//モデルの定義
@Id
private Integer id;
private String name;
private String email;
// 値を返す用の関数
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String gatEmail() {
return email;
}
}
▽ リポジトリ
package com.example.demo.repository;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.demo.entity.User;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
@Repository
public class SampleRepository {
@Autowired
private EntityManagerFactory entityManagerFactory;
// findAll()でUserのデータを取り出し、List型に代入する処理を定義している
@SuppressWarnings("unchecked")
public List<User> findAll() {
// userListの定義
List<User> userList = null;
// EntityManagerの開始
// EntityManagerは「DB操作パッケージ」のようなもの
EntityManager entityManager = entityManagerFactory.createEntityManager();
try {
// トランザクションの開始
entityManager.getTransaction().begin();
// Userエンティティから全てのデータを取得し、userListに代入
// createQueryは本来createQuery("Select * FROM User")やcreateQuery("Select u.name FROM User u")と記述するが、
// 「SELECT *」の場合は省略して「FROM Uuser」と書くことができる
userList = entityManager.createQuery("from User").getResultList();
// トランザクションのコミット(データベースへの変更を確定)
entityManager.getTransaction().commit();
} catch (Exception e) {
// エラーがあればロールバック(データベースへの変更を取り消し)
entityManager.getTransaction().rollback();
// エラーを吐く(エラーの詳細情報を出力)
e.printStackTrace();
} finally {
// EntityManagerの終了(リソースの解放)
entityManager.close();
}
// 取得したUserエンティティのリストを返す
// 失敗時はnull, 成功時はuserのデータが入ったList
return userList;
}
}
▽コントローラ
package com.example.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.entity.User;
import com.example.demo.repository.SampleRepository;
@RestController
public class SampleContoller {
@Autowired
private SampleRepository userRepository;
@GetMapping("/sample")
public List<User> getUser(){
return userRepository.findAll();
}
}
Userエンティティ(モデルのようなもの)を定義し、
リポジトリでエンティティを使用してデータを取得するメソッドを作成し、
そのメソッドを「/sampleアクセス時」にコントローラで呼んでいます。
Docker(DB)側
DB用意するの面倒なので、Dockerでサクッと立てちゃいます。
今回はMySQLにしました。
理由は特にないです。
version: "3.7"
services:
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=sample
- MYSQL_DATABASE=sampleDB
- MYSQL_USER=sampleUser
- MYSQL_PASSWORD=password
ports:
- "3306:3306"
volumes:
- ./init:/docker-entrypoint-initdb.d/
初期データを入れたかったので、
volumesで「docker-entrypoint-initdb.d」をマウントしてデータを差し込みます。
CREATE TABLE IF NOT EXISTS user (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL
);
INSERT INTO user(name, email)
VALUES ('John', 'John@gmail.com'),
('Tanaka', 'Tanaka@gmail.com');
dockerの場所はどこでも良かったのですが、今回はフロント側に入れときました。
「docker_mysql」ディレクトリが該当の場所です。
ビルドする
今はフロントとバックが各々動いている状態なので、結合します。
React側は以下コマンドでファイルをまとめます。
npm run build
distディレクトリが作成され、その中に成果物が入るので、それをまるっとSpring Bootに移動します。
場所は「src/main/resources/static」配下です。
移動するだけでOKです。
特に設定はいりません。
これでSpring Boot側にアプリがまとまったので、
最後にSpring Bootをビルドしてjarファイルにまとめます。
ルートで以下コマンドを入力
gradlew build
するとbuildディレクトリが作成され、
build/lib/ 配下に「jarファイル」が作成されます。
これ1つにすべてまとまってます。すごいですね。
試しに実行してみます。
java -jar build/libs/xxxx.jar ←自分のjarファイルの名前に合わせる
OK!!
dockerに入れておいた初期データをちゃんと持って来られてますね。
さいごに
あとはこのjarファイルをAWS上にデプロイし、
同じくAWSでDBを立ち上げれば誰でも使用可能になります。
その辺やりたいけど時間がない…ので来週中になんとか!頑張ります!
Javaはやっぱ難しい…
逆にDockerの楽さをひしひしと感じます。
今回はここまで!
Enjoy Hacking!!