Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product crud(Category 속성 -> 테이블 관리로 변경으로 인한 추가 개발) #65

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.ssafy.springbootapi.domain.product.api;

import com.ssafy.springbootapi.domain.product.application.CategoryService;
import com.ssafy.springbootapi.domain.product.domain.Category;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "Category", description = "Category 관련 API 입니다.")
@RestController
@RequiredArgsConstructor
//@CrossOrigin // spring security 디펜던시 삭제로 인한 주석처리
@RequestMapping("/api/v1/categories")
public class CategoryController {
private final CategoryService categoryService;

@Operation(summary = "모든 카테고리 조회")
@GetMapping
public ResponseEntity<List<Category>> getAllCategories() {
List<Category> categories = categoryService.getAllCategories();
return ResponseEntity.status(HttpStatus.OK).body(categories);
}

@Operation(summary = "카테고리 생성")
@PostMapping
public ResponseEntity<Category> createCategory(@RequestBody String name) {
Category category = categoryService.createCategory(name);
return ResponseEntity.status(HttpStatus.CREATED).body(category);
}

@Operation(summary = "카테고리 수정")
@PutMapping("/{id}")
public ResponseEntity<Category> updateCategory(@PathVariable Integer id, @RequestBody String name) {
return ResponseEntity.status(HttpStatus.OK).body(categoryService.updateCategory(id, name));
}

@Operation(summary = "카테고리 삭제")
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteCategory(@PathVariable Integer id) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(categoryService.deleteCategory(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.ssafy.springbootapi.domain.product.application;

import com.ssafy.springbootapi.domain.product.dao.CategoryRepository;
import com.ssafy.springbootapi.domain.product.domain.Category;
import com.ssafy.springbootapi.domain.product.exception.NotFoundCategoryException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class CategoryService {
private final CategoryRepository categoryRepository;

/**
* 카테고리 전체 조회
* @return List(Category)
*/
public List<Category> getAllCategories() {
return categoryRepository.findAll();
}

/**
* id로 카테고리 조회
* @param id : category id
* @return Category
*/
public Category getCategoryById(Integer id) {

return categoryRepository.findById(id).orElseThrow(()
-> new NotFoundCategoryException("Category not found with id : " + id));
}

/**
* 카테고리 생성
* @param name : 카테고리 이름
* @return 생성된 카테고리
*/
@Transactional
public Category createCategory(String name) {
try {
Category category = new Category();
category.setName(name);
return categoryRepository.save(category);
} catch(Exception E) {
return null;
}
}

/**
* 카테고리 이름 수정
* @param id : 수정할 카테고리 아이디
* @param name : 수정할 카테고리 이름
* @return 수정된 카테고리
*/
@Transactional
public Category updateCategory(Integer id, String name) {
Category category = findCategoryByIdOrThrow(id);
category.setName(name);
return category;
}

/**
* 카테고리 삭제
* @param id : 삭제할 카테고리 아이디
* @return 성공 여부
*/
@Transactional
public Boolean deleteCategory(Integer id) {
Category category = findCategoryByIdOrThrow(id);
try {
categoryRepository.delete(category);
return true;
} catch(Exception e) {
return false;
}
}

private Category findCategoryByIdOrThrow(Integer id) {
return categoryRepository.findById(id)
.orElseThrow(() -> new NotFoundCategoryException("Category Not Found"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.stream.Collectors;

import com.ssafy.springbootapi.domain.product.dao.ProductRepository;
import com.ssafy.springbootapi.domain.product.domain.Category;
import com.ssafy.springbootapi.domain.product.domain.Product;
import com.ssafy.springbootapi.domain.product.domain.ProductMapper;
import com.ssafy.springbootapi.domain.product.dto.ProductInput;
Expand All @@ -17,15 +18,14 @@
import com.ssafy.springbootapi.domain.user.exception.UserNotFoundException;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.server.ResponseStatusException;

@Service
@RequiredArgsConstructor
public class ProductService {
private final ProductRepository productRepository;
private final UserRepository userRepository;
private final CategoryService categoryService;
private final ProductMapper productMapper;


Expand Down Expand Up @@ -55,18 +55,22 @@ public ProductOutput getProductById(Long id) {
* @param productInput : Product 생성 데이터
* @return ProductOutput(DTO)
*/
@Transactional
public ProductOutput insertProduct(ProductInput productInput) {
// user_id로 User 객체 찾기
Optional<User> userOptional = userRepository.findById(productInput.getUser_id());
User user = userOptional.orElseThrow(() ->
new UserNotFoundException("User not found with id: " + productInput.getUser_id())
);

Category category = findCategoryByIdOrThrow(productInput.getCategory_id());

// ProductInput에서 Product 엔티티로 변환
Product product = productMapper.toEntity(productInput);

// User 객체를 Product 엔티티에 설정
product.setUser(user);
product.setCategory(category);

// Product 엔티티를 DB에 저장하고, 저장된 엔티티를 ProductOutput DTO로 변환하여 반환
return productMapper.toProductOutput(productRepository.save(product));
Expand All @@ -78,6 +82,7 @@ public ProductOutput insertProduct(ProductInput productInput) {
* @param id : 삭제할 product id
* @return ProductOutput(DTO)
*/
@Transactional
public ProductOutput removeProduct(Long id) {
Product toRemove = findProductByIdOrThrow(id);
productRepository.delete(toRemove);
Expand All @@ -93,6 +98,10 @@ public ProductOutput removeProduct(Long id) {
@Transactional
public ProductOutput updateProduct(Long id, ProductUpdate productUpdate) {
Product productToUpdate = findProductByIdOrThrow(id);
if(productUpdate.getCategory_id() != null) {
Category category = findCategoryByIdOrThrow(productUpdate.getCategory_id());
productToUpdate.setCategory(category);
}
productMapper.updateProduct(productUpdate, productToUpdate);
return productMapper.toProductOutput(productRepository.save(productToUpdate));
}
Expand All @@ -106,4 +115,13 @@ private Product findProductByIdOrThrow(Long id) {
return productRepository.findById(id)
.orElseThrow(() -> new NotFoundProductException("Product not found with id: " + id));
}

/**
* id로 카테고리 찾기. 없을 경우 Exception 발생
* @param categoryId : 찾을 category 아이디
* @return 카테고리
*/
private Category findCategoryByIdOrThrow(Integer categoryId) {
return categoryService.getCategoryById(categoryId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ssafy.springbootapi.domain.product.dao;

import com.ssafy.springbootapi.domain.product.domain.Category;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CategoryRepository extends JpaRepository<Category, Integer> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ssafy.springbootapi.domain.product.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "category")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Category {
@Id
@GeneratedValue
@Column(name = "id", unique = true)
private Integer id;

@Column(name = "name")
private String name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,24 @@ public class Product {
private String name;

@Column(name = "price", nullable = false)
private int price;
private Integer price;

@Column(name = "description", nullable = false)
private String description;

@Column(nullable = false)
private int category;
@ManyToOne
@JoinColumn(name="category_id", nullable = false)
private Category category;

@Column(nullable = false)
private int stock;
private Integer stock;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
// @Column(name = "user_id")
// private int userId;

// test code를 위해 추가
public void updateInfo(int category, int stock, String imageUrl) {
this.category = category;
public void updateInfo(int stock, String imageUrl) {
this.stock = stock;
this.imageUrl = imageUrl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
public class ProductBase {
private String imageUrl;
private String name;
private int price;
private Integer price;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
@SuperBuilder
public class ProductInput extends ProductBase {
private String description;
private int category;
private int stock;
@NotBlank(message = "category id is required")
private Integer category_id;
private Integer stock;
@NotBlank(message = "user id is required")
private Long user_id;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.ssafy.springbootapi.domain.product.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
Expand All @@ -12,7 +11,5 @@
@SuperBuilder
public class ProductOutput extends ProductListOutput{
private String description;
private int category;
private int stock;
// private int user_id;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;

@AllArgsConstructor
Expand All @@ -12,6 +11,6 @@
@SuperBuilder
public class ProductUpdate extends ProductBase {
private String description;
private int category;
private int stock;
private Integer category_id;
private Integer stock;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ssafy.springbootapi.domain.product.exception;

public class NotFoundCategoryException extends RuntimeException{
public NotFoundCategoryException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ssafy.springbootapi.global.error;

import com.ssafy.springbootapi.domain.product.exception.NotFoundCategoryException;
import com.ssafy.springbootapi.domain.product.exception.NotFoundProductException;
import com.ssafy.springbootapi.domain.user.exception.UserNotFoundException;
import org.springframework.http.HttpStatus;
Expand All @@ -15,6 +16,11 @@ public ResponseEntity<?> handleNotFoundProductException(NotFoundProductException
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}

@ExceptionHandler(NotFoundCategoryException.class)
public ResponseEntity<?> handleNotFoundCategoryException(NotFoundCategoryException ex) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
}

@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {
return ResponseEntity
Expand Down
Loading