์ค๋๋ ์ค์ ๊ณผ ์คํ ๋๋ค ํ ํ๋ก์ ํธ๋ฅผ ์งํํ์๊ณ , ์คํ์๋ ํ๋ก์ ํธ์ ํ์์ ์ผ๋ก ๋ฆฌ์กํธ ๊ธฐ์ ์ ์ถ๊ฐํด์ผํ๋ค๊ณ ํ์ฌ ์คํ์๋ ์ฑ GPT์ ํจ๊ป ๋ฆฌ์กํธ๋ฅผ ์ ์ฉํ์๋ค.
โก ์๋น์ค ํด๋์ค๊ฐ ๋ค๋ฅธ ์๋น์ค ํด๋์ค๋ฅผ ์์กดํด๋ ๋๋๊ฐ์ ๋ํ ๊ถ๊ธ์ฆ ์ด์์ต๋๋ค. ์๋ ์ฝ๋๋ฅผ ๋ณด๊ณ ์ ๋ฆฌ ํด๋ณด๊ฒ ์ต๋๋ค.
์๋์ ์ฝ๋๋ ์ํ์ ์ด๋ฏธ์ง์ ํจ๊ป ๋ฑ๋กํ ์ ์๋ ๋ฉ์๋๊ฐ ์กด์ฌํ๋ ์๋น์ค ํด๋์ค ์ ๋๋ค.
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ProductServiceImpl implements ProductService {
private final ProductRepository productRepository;
private final ImageRepository imageRepository;
@Value("${spring.servlet.multipart.location}")
private String productImagePath;
@Override
@Transactional
public void createProductWithImage(CreateRequest createRequest,
MultipartFile images) throws IOException {
if (!isImageExists(images)) {
initProduct(createRequest);
}
if (isImageExists(images)) {
String imageLocation = productImagePath;
Product product = initProduct(createRequest);
for (MultipartFile image : images) {
String imageName = image.getOriginalFilename();
String imagePath = imageLocation + imageName;
// ์ด๋ฏธ์ง ๊ด๋ จ IOException
validateCreateDirectory(imageLocation);
validateTransferImage(imagePath, image);
// ์ํ์ ์ฐ๊ด๊ด๊ณ์ธ ๋ฉ์๋๋ฅผ ํตํด ์ด๋ฏธ์ง ์ ์ฅ
Image productImage = Product.createProductImage(imagePath);
product.addProductImage(productImage);
imageRepository.save(productImage);
}
}
}
}
ํด๋น ProductServiceImpl ํด๋์ค์์๋ Product ๋ ํฌ์งํ ๋ฆฌ์ Image ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ์์กด์ฑ ์ฃผ์
์ ๋ฐ์ createProductWithImage ๋ฉ์๋๋ฅผ ํตํด Product ๋ฅผ ์ ์ฅํ๊ณ Image ๋ฅผ ์ ์ฅํ๊ฒ ๋ฉ๋๋ค.
์ด ๋ถ๋ถ์์ ํ๋์ ๋ฉ์๋๊ฐ ๋ง์ ๊ธฐ๋ฅ์ ์ํํ๊ณ ์๋ค๊ณ ์๊ฐํ์๊ณ , Image ๋ ํฌ์งํ ๋ฆฌ๋ฅผ ProductServiceImpl ํด๋์ค์ ์์กดํ ํ์๊ฐ ์๋ค๊ณ ์๊ฐ ํ์์ต๋๋ค. โก (ImageServiceImpl ํด๋์ค๋ฅผ ์์ฑ)
๊ฐ์ ํ ์ฝ๋ ์ ๋๋ค.
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ProductServiceImpl implements ProductService {
private final ProductRepository productRepository;
private final ImageService imageService;
@Override
@Transactional
public void createProductWithImage(CreateRequest createRequest,
MultipartFile images) throws IOException {
if (!isImageExists(images)) {
initProduct(createRequest);
}
if (isImageExists(images)) {
Product product = initProduct(createRequest);
imageService.uploadImage(product, images);
}
}
}
โก ProductServiceImpl ํด๋์ค์์๋ ์ํ๋ง ์ ์ฅํ๋ฉฐ, imageService ํด๋์ค์ uploadImage ๋ฉ์๋์ Product ๊ฐ์ฒด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๊ฒ ๋ฉ๋๋ค. ์ฆ ์ด๋ง์ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ ์ฝ๋๋ ์๋์ ๊ฐ์ด ImageService ์์ ์ฒ๋ฆฌ ํ๋ค๋ ๋ป ์
๋๋ค.
@Service
@RequiredArgsConstructor
public class ImageServiceImpl implements ImageService {
private final ImageRepository imageRepository;
@Value("${spring.servlet.multipart.location}")
private String productImagePath;
// Product ๊ฐ์ฒด๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๋ฉด์, ๋ฉ์๋๋ฅผ ๋ถ๋ฆฌ ํ์๋ค.
@Transactional
public void uploadImage(Product product,
MultipartFile image) throws IOException {
String imageLocation = productImagePath;
String imageName = image.getOriginalFilename();
String imagePath = imageLocation + imageName;
// ์ด๋ฏธ์ง ๊ด๋ จ IOException
validateCreateDirectory(imageLocation);
validateTransferImage(imagePath, image);
// ์ํ์ ์ฐ๊ด๊ด๊ณ์ธ ๋ฉ์๋๋ฅผ ํตํด ์ด๋ฏธ์ง ์ ์ฅ
Image productImage = Product.createProductImage(imagePath);
product.addProductImage(productImage);
imageRepository.save(productImage);
}
}
์ฌ๋ฌ ์๋ฃ์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐพ์๋ณด๋ฉฐ ์ฌ๋ฌ ๊ธ์ด ์์์ง๋ง, ์๋น์ค ๋จ์์๋ ๋ ํฌ์งํ ๋ฆฌ๋ง ์์กด์ฑ ์ฃผ์ ์ ํ์ฌ ์ป๋ ์ฅ์ ์ด ์๊ธฐ๋ ํ์ผ๋ฉฐ, ์๋น์ค ํด๋์ค๋ ๋ค๋ฅธ ์๋น์ค๋ฅผ ์์กด์ฑ ์ฃผ์ ์ ๋ฐ์ ์๋น์ค ๋ ์ด์ด (๊ณ์ธต)์ ๋ถ๋ฆฌํ์ฌ ์ป๋ ์ฅ์ ์ด ์๋ค๊ณ ํฉ๋๋ค. ์ํฉ์ ๋ง์ถฐ ์ฅ๋จ์ ์ ์ฐพ์๋ณด๋ฉฐ ์ ์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
vs code IDE (๊ฐ๋ฐ๋๊ตฌ) ์์ Node.js๋ฅผ ์ค์นํ๊ณ ๋ฆฌ์กํธ๋ฅผ ์ค์น ํ์๋ค.
๋ฆฌ์กํธ ๊ธฐ์ ์ ๋ํด์๋ ์์ ๋ฌธ์ธํ์ด๋ผ ์ฑ GPT์ ํ์๋ถ๊ป ๋์์ ๋ฐ์ผ๋ฉด์ ํ๋ก ํธ ์ชฝ ์์ ์ ํ์๊ณ , ๋ด์ผ๊น์ง ๋์์ ๋ฐ์์ผ ๋ ๊ฒ ๊ฐ๋ค..