技術系

Java × React × Dockerで簡易アプリ作るよ

技術系

こんにちは、なかにしです。

現在は業務で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!!

タイトルとURLをコピーしました