Springでファイルパスを使い画像をアップロードする。

# テーブル
```sql:images
CREATE TABLE images (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  file_path VARCHAR(255) NOT NULL
);

```
# Entity
```Java:ImageEntity
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "images")
public class ImageEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name; // 画像ファイル名
    @Column(name = "file_path")
    private String filePath; // 画像ファイルのパス
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getFilePath() {
		return filePath;
	}
	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

}
```
# Repository
```java:ImageRepository
import org.springframework.data.jpa.repository.JpaRepository;

public interface ImageRepository extends JpaRepository<ImageEntity, Long> {
}
```
# Controller
```java:ImageUploadController
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;

@Controller
public class ImageUploadController {

    @Autowired
    private ImageRepository imageRepository;

    private static final String UPLOAD_DIR = "uploads"; // アップロード先のディレクトリ

    @GetMapping("/")
    public String index() {
        return "upload";
    }

    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
        try {
            // アップロードディレクトリが存在しない場合、作成
            File uploadDir = new File(UPLOAD_DIR);
            if (!uploadDir.exists()) {
                uploadDir.mkdirs();
            }

            // 画像ファイルの保存先パス
            String filePath = UPLOAD_DIR + File.separator + file.getOriginalFilename();

            // 画像ファイルをディスクに保存
            Path destination = new File(filePath).toPath();
            Files.copy(file.getInputStream(), destination, StandardCopyOption.REPLACE_EXISTING);

            // データベースにファイルメタデータを保存
            ImageEntity imageEntity = new ImageEntity();
            imageEntity.setName(file.getOriginalFilename());
            imageEntity.setFilePath(filePath);
            imageRepository.save(imageEntity);

            redirectAttributes.addFlashAttribute("message", "File uploaded successfully!");
        } catch (IOException e) {
            redirectAttributes.addFlashAttribute("error", "Failed to upload file: " + e.getMessage());
        }

        return "redirect:/";
    }
}
```
# HTML
```html:upload
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>画像アップロード</title>
</head>
<body>
    <h1>画像アップロード</h1>
    <form th:action="@{/upload}" method="post" enctype="multipart/form-data">
        <input type="file" name="file" accept="image/*">
        <input type="submit" value="アップロード">
    </form>
    
    <div th:if="${message}" class="success">
        <p th:text="${message}"></p>
    </div>
    
    <div th:if="${error}" class="error">
        <p th:text="${error}"></p>
    </div>
</body>
</html>

```
# build.gradle
```gradle:build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.1.3'
	id 'io.spring.dependency-management' version '1.1.3'
}

group = 'com.demo'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.2'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.mysql:mysql-connector-j'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.2'
}

tasks.named('test') {
	useJUnitPlatform()
}
```
# application.properties
```
spring.datasource.url=jdbc:mysql://localhost:3306/データベース名
spring.datasource.username=ユーザー名
spring.datasource.password=パスワード
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
```
# 画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/37a0df13-e077-f02f-4895-82877c345014.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/0f5c1dd1-3b00-99cc-cfc7-dc9ab79328bb.png)

# データベース確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287651/9769cc4a-9936-85c2-75ea-43a9b27bf2cf.png)