0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring boot学習 (Sring boot + Typscript + RDS)

Last updated at Posted at 2024-12-16

spring boot 初学者向け
spring bootの学習のために、フロントからバックエンドまでを大まかにどうコードを書いていけばいいかを知りたくまとめました。
簡単なフロントとバックとデータベースを作成しましたので記事として残します

結果イメージ
フロントで「user」「email」を入力して、「DBに保存」ボタンを押すと、DBに保存される
フロントで検索したいuserを文字列として入力して、「検索」ボタンを押すと、DBに保存されているuserと対となるemailが表示される


作成手順

フロントエンドの準備
1.任意の場所に「spring-kotlin-vite-mysql-study」フォルダを作成
2.ターミナルで作成したフォルダへ移動しコマンドで「npm create vite」を入力し、Project nameはfrontendと入力しEnterを押し、次に矢印キーでReactを選択しEnterを押し、Typscritpを選択しEnterを押下する。
3.frontというフォルダが中身も含め作成されるので、これをVSCodeなどで開く
4.「npm install」を実行
5.以下のフォルダ構成で
App.tsx,
api.ts,
getEmailByUsername.ts
の3つのファイルを以下のコードで作成する
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── api.ts
│   ├── assets
│   ├── getEmailByUsername.ts
│   ├── index.css
│   ├── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json

App.tsxファイル

import { useState } from 'react'
import './App.css'
import {saveUser} from "./api.ts";
import {getEmailByUsername} from "./getEmailByUsername.ts";

function App() {
    const [username, setUserName] = useState("");
    const [email, setEmail] = useState("")
    const [searchUsername, setSearchUsername] = useState("");
    const [fetchedEmail, setFetchedEmail] = useState("")


    const handleSave = async () => {
        try{
            const response = await saveUser({username, email});
            alert(response.message)
        }
        catch(error){
            alert("Error saving user!")
        }
    }

    const handleSearch = async () => {
        console.log("searchUsername",searchUsername)
        try{
            const response = await getEmailByUsername(searchUsername);
            setFetchedEmail(response.email)
        } catch(error){
            alert("Error fetching email!")
        }
    }

  return (
    <>
        <div>
            <h3>DEMO</h3>
            <h4>spring boot + kotlin/ vite+Typscript/ MySQL</h4>
            <label>名前
                <input type="text" value={username} onChange={(e) => setUserName(e.target.value)}/>
            </label>
            <br />
            <label>メール
                <input type="text" value={email} onChange={(e) => setEmail(e.target.value)}/>
            </label>
            <br />
            <button onClick={handleSave}>DBに保存</button>
            <br />

            <label>検索する名前
                <input type="text" value={searchUsername} onChange={(e)=>setSearchUsername(e.target.value)}/>
            </label>
            <br />
            <button onClick={handleSearch}>検索</button>
            {fetchedEmail && (
                <div>
                    <h4>取得したメールアドレス:{fetchedEmail}</h4>
                </div>
            )}
        </div>
    </>
  )
}

export default App

api.ts

export const saveUser = async (user:{username:string, email:string}) => {
    const response = await fetch("http://localhost:8080/users",{
        method:"POST",
        headers:{"Content-Type": "application/json"},
        body:JSON.stringify(user)
    });

    if(!response.ok) throw new Error("Failed to save user");
    console.log("response",response)
    return response.json()
}

getEmailByUsername.ts

export const getEmailByUsername = async (username) => {
    console.log("searchUsername-getEmaulByUSername",username)
    const response = await fetch(`http://localhost:8080/users/${username}`,{
        method:"GET",
        headers:{"Content-Type": "application/json"},
    });
    if(!response.ok) throw new Error("Failed to get mail");
    return response.json()
}

6.「npm run dev」を実行
7.ブラウザを開き、http://localhost:5174/ を入力する
 (他にnpm run devしているアプリがある時は5174ではない場合があります)
8.以下のように表示されればfrontendの準備は完了
image.png


バックエンドの準備

1.spring initializrを開く
2.Artifactに「backend」と記入し、右上のADD DEPENDENCIESを押してSring webを選択する
3.下部のGENERATEを押す
image.png
4.ダウンロードしたzipファイルを解凍して、「spring-kotlin-vite-mysql-study」の中に保存する
5.backendフォルダを開く
6.以下のフォルダ構成で
Userクラス
UserControllerクラス
UserRepositoryクラス
UserServiceクラス
application.properties
build.gradle.kts
docker-compose.yml
の7つのファイルを以下のコードで作成する
image.png

Userクラス

package com.example.backend

import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id

@Entity
data class User(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id:Long = 0,
    val username:String,
    val email:String
)

UserControllerクラス

package com.example.backend

import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/users")
@CrossOrigin(origins = ["http://localhost:5173"])//CORS対応

class UserController (private val service:UserService){
    @PostMapping
    fun createUser(@RequestBody user:User):Map<String, String>{
        service.saveUser(user)
        return mapOf("message" to "User saved successfully!")
    }

    @GetMapping("/{username}")
    fun getEmailByUsername(@PathVariable username: String): Map<String, String> {
        val email: String? = service.findEmailByUsername(username)
        return mapOf("email" to (email ?: "User not found"))
    }

}

UserRepositoryクラス

package com.example.backend

import org.springframework.data.jpa.repository.JpaRepository

interface UserRepository : JpaRepository<User, Long> {
    fun findByUsername(username: String): User?
}

UserServiceクラス

package com.example.backend

import org.springframework.stereotype.Service

@Service
class UserService (private val repository:UserRepository){
    fun saveUser(user:User):User = repository.save(user)

    fun findEmailByUsername(username:String):String?{
        val user = repository.findByUsername(username)
        return user?.email
    }
}

application.properties

spring.application.name=mysql-test
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=user
spring.datasource.password=password6
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.cloud.config.enabled=false
#spring.config.import=configserver:

build.gradle.kts

plugins {
	kotlin("jvm") version "1.9.25"
	kotlin("plugin.spring") version "1.9.25"
	id("org.springframework.boot") version "3.4.0"
	id("io.spring.dependency-management") version "1.1.6"

	kotlin("plugin.jpa") version "1.9.10"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

repositories {
	mavenCentral()
}

extra["springCloudVersion"] = "2024.0.0"

dependencies {
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
	implementation("org.jetbrains.kotlin:kotlin-reflect")
	implementation("org.springframework.cloud:spring-cloud-starter-config")
	runtimeOnly("com.mysql:mysql-connector-j")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
	testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
	testRuntimeOnly("org.junit.platform:junit-platform-launcher")

	testImplementation("org.mockito.kotlin:mockito-kotlin:5.1.0") // 最新版を使用
	testImplementation("org.springframework.boot:spring-boot-starter-test") {
		exclude(group = "org.mockito", module = "mockito-core")
	}

	implementation("jakarta.persistence:jakarta.persistence-api:3.1.0") // Jakarta Persistence API
	implementation("org.springframework.boot:spring-boot-starter-data-jpa") // Spring Data JPA
}


dependencyManagement {
	imports {
		mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
	}
}

kotlin {
	compilerOptions {
		freeCompilerArgs.addAll("-Xjsr305=strict")
	}
}

tasks.withType<Test> {
	useJUnitPlatform()
}

docker-compose.yml

version: '3.8'

services:
  mysql:
    image: mysql:latest
    container_name: mysql-kotlin-2024_12_09
    restart: always
    environment:
      MYSQL_USER: user
      MYSQL_ROOT_PASSWORD: mysql112233
      MYSQL_PASSWORD: password6
      MYSQL_DATABASE: demo
    ports:
      - "3306:3306"
    volumes:
      - ./mysql_data:/var/lib/mysql  # ローカルディレクトリを指定

volumes:
  mysql_data:

バックエンドの起動方法
9.dockerの起動
Macターミナルで、上記で作成したdocker-compose.ymlファイルがある場所で
docker compose up -d
を実行
10.BackendApplicaiton.ktでバックエンド起動(再生ボタン押下)


フロント→バックエンド→データベースへの動作確認
11.先ほどnpm run devで起動したフロント画面で、userとemailを入力して、「DBに保存」ボタンを押す。
12.先ほどuser欄で入力した文字を検索する名前の欄に入力して「検索」を押すと、emailが表示される
13.以上

これでフロントエンド→バックエンド→データベースの動作がspringではどうやって動作するのがかイメージするのに役立てればと思います。


参考
mysqlへ直接データが保存されているかの確認方法
・ターミナルで

docker exec -it mysql-kotlin-2024_12_09 mysql -u root  -p
mysql112233 
USE demo; 
select * from user;  

以下のようにデータがあるかを確認できる
image.png

8080が起動しているか確認するコマンド
lsof -i:8080
停止は kill プロセスID

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?