
[ 업데이트는 조금 다르다. save에서 한 코드를 그대로 사용하면 ]

제목만 바꾸고 싶어서 업데이트하니까 사진 엑박 뜸. 사진도 무조건 새로운 사진으로 업로드를 해야지만 사진이 나온다... -> 기존의 이미지 파일명을 유지하지 않고 새로운 파일명을 할당하기 때문에 발생
[ update-form.mustache 수정 ]
{{> layout/header}}
<div class="container" style="margin-top: 5%; margin-bottom: 5%">
<div class="row">
<!-- 이미지와 상품 정보를 함께 업로드하는 섹션 -->
<div class="col-lg-15 mb-4 mb-lg-0">
<form id="productForm" action="/product/{{id}}/update" method="post" enctype="multipart/form-data">
<div class="row">
<div class="form-group mt-3 col-3" style="margin-left: 10%;">
<img id="previewImg" src="/upload/{{product.imgFileName}}" width="300" height="300" style="border-radius: 5%;">
<div class="mt-3">
<input type="file" class="form-control" id="imgFile" name="imgFile" accept="image/*">
</div>
</div>
<div class="col-lg-6">
<div class="mb-3 mt-3">
상 품 명 : <input id="name" name="name" type="text" class="form-control" value="{{product.name}}">
<div class="alert alert-danger" id="nameCheck">상품명을 입력해주세요</div>
</div>
<div class="mb-3 mt-3">
상품가격 : <input id="price" name="price" type="text" class="form-control" value="{{product.price}}">
</div>
<div class="mb-3 mt-3">
상품수량 : <input id="qty" name="qty" type="text" class="form-control" value="{{product.qty}}">
</div>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-success mt-2">상품등록완료</button>
</div>
</div>
</div>
</form>
</div>
<!-- 이미지와 상품 정보를 함께 업로드하는 섹션 -->
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
// imgFile input 필드에 event listener 추가
document.getElementById('imgFile').addEventListener('change', function(event) {
var output = document.querySelector('img'); // 미리보기를 할 이미지 태그 선택
if (event.target.files && event.target.files[0]) {
// FileReader 객체를 이용해 파일을 읽음
var reader = new FileReader();
reader.onload = function(e) {
output.src = e.target.result; // 읽은 파일의 내용을 img 태그의 src 속성에 할당
output.style.display = 'block'; // 이미지 태그를 화면에 표시
};
reader.readAsDataURL(event.target.files[0]); // 파일 읽기 시작
}
});
});
</script>
<script src="/js/name-check.js"></script>
<script src="/js/detail.js"></script>
{{> layout/footer}}
[ ProductResponse ]
@Data
public static class UpdateDTO {
private Integer id;
private String name;
private Integer price;
private Integer qty;
private String imgFileName;
@Builder
public UpdateDTO(Product product) {
this.id = product.getId();
this.name = product.getName();
this.price = product.getPrice();
this.qty = product.getQty();
this.imgFileName = product.getImgFileName();
}
}
[ ProductController ]
1. update-form
//업데이트 폼 (업데이트는 2개가 나와야합니다 ^^)
@GetMapping("/product/{id}/update-form")
public String updateForm(@PathVariable Integer id, HttpServletRequest request) {
ProductResponse.UpdateDTO product = productService.findByIdUpdate(id);
request.setAttribute("product", product);
System.out.println(product);
return "/product/update-form";
}
2. update
//업데이트
@PostMapping("/product/{id}/update")
public String update(@PathVariable Integer id, ProductRequest.UpdateDTO requestDTO) {
String imgFileName;
// 이미지 파일이 존재할 경우, 새 파일명 생성 및 파일 저장
if (!requestDTO.getImgFile().isEmpty()) {
MultipartFile imgFile = requestDTO.getImgFile();
imgFileName = UUID.randomUUID() + "_" + imgFile.getOriginalFilename();
Path imgPath = Paths.get("./upload/" + imgFileName);
try {
//upload 디렉토리가 존재하지 않는다면, 서버가 시작될 때 해당 디렉토리를 자동으로 생성하는 코드
//static에 안 넣으려고 설정해줬나봄
Files.createDirectories(imgPath.getParent());
Files.write(imgPath, imgFile.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
// 이미지 파일이 없을 경우, 기존 파일명 유지
ProductResponse.UpdateDTO existImg = productService.findByIdUpdate(id);
imgFileName = existImg.getImgFileName(); // 기존의 imgFileName을 가져와서 사용
}
productService.updateById(id, requestDTO, imgFileName);
return "redirect:/product/" + id;
}
requestDTO.getImgFile이 비어있지 않으면, 정상적으로 UUID를 사용해 새로운 이미지를 저장하고, 새롭게 받은 이미지 파일이 없으면 기존의 업데이트 폼에 있던 정보를 조회해서 그 정보를 imgFileName 변수에 할당, productService.updateById(id, requestDTO, imgFileName); 이렇게 업데이트 친다!
[ ProductService ]
1. update-form
//상품 업데이트 폼 보기
public ProductResponse.UpdateDTO findByIdUpdate(Integer id) {
Product product = productRepo.findById(id);
return new ProductResponse.UpdateDTO(product);
}
2. update
// 상품 업데이트
@Transactional
public void updateById(Integer id, ProductRequest.UpdateDTO requestDTO, String imgFileName) {
productRepo.updateById(id, requestDTO, imgFileName);
}
[ ProductRepository ]
1. update-form
//상품 상세보기
public Product findById(Integer id) {
String q = """
select * from product_tb where id = ?
""";
Query query = em.createNativeQuery(q, Product.class);
query.setParameter(1, id);
Product result = (Product) query.getSingleResult();
return result;
}
2. update
//상품 수정하기
public void updateById(Integer id, ProductRequest.UpdateDTO requestDTO, String imgFileName) {
String q = """
update product_tb set name = ?, price = ?, qty = ?, img_file_name = ? where id = ?
""";
Query query = em.createNativeQuery(q);
query.setParameter(1, requestDTO.getName());
query.setParameter(2, requestDTO.getPrice());
query.setParameter(3, requestDTO.getQty());
query.setParameter(4, imgFileName);
query.setParameter(5, id);
query.executeUpdate();
}
[ 이미지가 보여야할 곳에 머스태치 뿌리기 ]
1. update-form.mustache
{{> layout/header}}
<div class="container" style="margin-top: 5%; margin-bottom: 5%">
<div class="row">
<!-- 이미지와 상품 정보를 함께 업로드하는 섹션 -->
<div class="col-lg-15 mb-4 mb-lg-0">
<form id="productForm" action="/product/{{id}}/update" method="post" enctype="multipart/form-data">
<div class="row">
<div class="form-group mt-3 col-3" style="margin-left: 10%;">
<img id="previewImg" src="/upload/{{product.imgFileName}}" width="300" height="300" style="border-radius: 5%;">
<div class="mt-3">
<input type="file" class="form-control" id="imgFile" name="imgFile" accept="image/*">
</div>
</div>
<div class="col-lg-6">
<div class="mb-3 mt-3">
상 품 명 : <input id="name" name="name" type="text" class="form-control" value="{{product.name}}">
<div class="alert alert-danger" id="nameCheck">상품명을 입력해주세요</div>
</div>
<div class="mb-3 mt-3">
상품가격 : <input id="price" name="price" type="text" class="form-control" value="{{product.price}}">
</div>
<div class="mb-3 mt-3">
상품수량 : <input id="qty" name="qty" type="text" class="form-control" value="{{product.qty}}">
</div>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-success mt-2">상품등록완료</button>
</div>
</div>
</div>
</form>
</div>
<!-- 이미지와 상품 정보를 함께 업로드하는 섹션 -->
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
// imgFile input 필드에 event listener 추가
document.getElementById('imgFile').addEventListener('change', function(event) {
var output = document.querySelector('img'); // 미리보기를 할 이미지 태그 선택
if (event.target.files && event.target.files[0]) {
// FileReader 객체를 이용해 파일을 읽음
var reader = new FileReader();
reader.onload = function(e) {
output.src = e.target.result; // 읽은 파일의 내용을 img 태그의 src 속성에 할당
output.style.display = 'block'; // 이미지 태그를 화면에 표시
};
reader.readAsDataURL(event.target.files[0]); // 파일 읽기 시작
}
});
});
</script>
<script src="/js/name-check.js"></script>
<script src="/js/detail.js"></script>
{{> layout/footer}}
[ 결과 화면 ]


변경 됨

이름만 바꿔도 변경 됨
Share article