BLOB 파일 저장

KimSeonGyu·2023년 9월 5일
0

SpringFramework(공부)

목록 보기
6/7
post-thumbnail

이번에는 스프링 부트를 이용해서 파일(이미지) 업로드를 하는 방법에 대해 알아보려합니다.
파일을 업로드하는 방법은 대표적으로 BLOB 와 파일 경로저장 방법입니다.

BLOB (Binary Large Object)

BLOB 방법은 이진 형식의 데이터를 직접 데이터베이스에 저장하는 방법입니다.
파일 자체가 데이터베이스에 저장되므로 별도의 경로나 URL이 필요 없습니다.

장점 :

  • 백업 및 복구가 용이
  • 데이터 일관성 유지
  • 파일 접근을 강력하게 제어가능
  • 파일 보안 강화

단점 :

  • 데이터 베이스의 크기가 빠르게 증가할 우려가 있음
  • 백업 및 복구 작업이 복잡해질 수 있음
  • 데이터 베이스 I/O 작업이 더 많아질 수 있음
  • 성능 저하 문제가 발생할 수 있음

저장방법

build.gradle
persistence.xml
이 외 설정 파일은 여기를 참고 해주시면 됩니다.

우선 큰틀에서 설명드리겠습니다.
1. html form태그에서 이미지(jpeg)파일을 업로드를 받으면
2. 데이터 베이스에 BLOB 형태로 저장이 되고
3. 이 데이터를 사용하기위해 서비스 객체에서 파싱을 하고
4. 타임리프를 이용해 html에 표시합니다.

이미지 업로드

h1>이미지 업로드</h1>

<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
    <input type="file" name="file" accept="image/*">
    <br>
    <button type="submit">업로드</button>
</form>


<a th:href="@{/image-list}">List로 가기</a>

컨트롤러

@Controller
@RequestMapping("/")
public class ImageController {

    private final ImageService imageService;

    @Autowired
    public ImageController(ImageService imageService) {
        this.imageService = imageService;
    }

    @GetMapping("/")
    public String showUploadForm() {
        return "image-test.html"; // upload.html 템플릿을 보여줍니다.
    }

    @PostMapping("/upload")
    public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
        // 파일 이름을 파라미터로 받아서 이미지 서비스로 전달
        String fileName = file.getOriginalFilename();
        imageService.uploadImage(fileName, file);

        return "image-test";

    }

    @GetMapping("/image-list")
    public String listImages(Model model) {
        List<Image> images = imageService.getAllImages();
        model.addAttribute("images", images); // Thymeleaf에 이미지 목록을 전달
        return "image-list"; // Thymeleaf 템플릿 이름 반환
    }


    @GetMapping("/image/{id}")
    public ResponseEntity<byte[]> getImage(@PathVariable Long id) {
        Optional<Image> image = imageService.getImageById(id);
        if (image.isPresent()) {
            byte[] imageData = image.get().getData();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG); // 이미지 유형에 맞게 수정
            return new ResponseEntity<>(imageData, headers, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }


}

서비스객체

@Service
public class ImageService {

    private final ImageRepository imageRepository;

    @Autowired
    public ImageService(ImageRepository imageRepository) {
        this.imageRepository = imageRepository;
    }
    public void uploadImage(String fileName, MultipartFile file) throws IOException {
        Image image = new Image();
        image.setFileName(fileName);
        image.setData(file.getBytes());
        imageRepository.save(image);
    }

    public List<Image> getAllImages() {
        return imageRepository.findAll();
    }

    // 이미지 조회 메서드
    public Optional<Image> getImageById(Long id) {
        return imageRepository.findById(id);
    }

}

이미지 리스트

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>업로드된 이미지 목록</title>
</head>
<body>
<h1>업로드된 이미지 목록</h1>

<!-- 이미지 목록을 표시하는 반복문 -->
<div th:each="image : ${images}">
  <h3 th:text="${image.fileName}"></h3>
  <!-- 이미지를 표시 -->
  <img th:src="@{'/image/' + ${image.id}}" width="300" height="200" alt="Uploaded Image">
</div>

<!-- 이미지 업로드 폼으로 이동하는 링크 -->
<br>
<a th:href="@{/}">이미지 업로드 페이지로 이동</a>
</body>
</html>

form 요소에서 다음과 같이 업로드를 한다.

그러면 컨트롤러에서

@PostMapping("/upload")
   public String uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
       // 파일 이름을 파라미터로 받아서 이미지 서비스로 전달
       String fileName = file.getOriginalFilename();
       imageService.uploadImage(fileName, file);

       return "image-test";

   }

이 실행돼 서비스객체의 uploadImage 메서드로 데이터베이스에 BLOB 형태로 저장된다.

마지막으로 이미지 리스트를 업로드하기위해서 list버튼을 클릭하면 컨트롤로에서 서비스객체의 uploadImage메서드를 호출해 BLOB 형태의 데이터를 파싱하게 되면 화면에

이렇게 출력된다.

profile
공부한 내용을 작성하는 블로그 입니다. 수정할 부분이 있다면 편하게 댓글 작성부탁드립니다!

0개의 댓글