-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from SSapingMall/product-crud
Product crud
- Loading branch information
Showing
17 changed files
with
586 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
...-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/api/ProductController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.ssafy.springbootapi.domain.product.api; | ||
|
||
import java.util.List; | ||
|
||
import com.ssafy.springbootapi.domain.product.application.ProductService; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductInput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductListOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductUpdate; | ||
import com.ssafy.springbootapi.global.aop.annotation.ToException; | ||
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.*; | ||
|
||
@Tag(name = "Product", description = "Product 관련 API 입니다.") | ||
@RestController | ||
@RequiredArgsConstructor | ||
//@CrossOrigin // spring security 디펜던시 삭제로 인한 주석처리 | ||
@RequestMapping("/api/v1/products") | ||
public class ProductController { | ||
private final ProductService productService; | ||
|
||
@Operation(summary = "모든 제품 조회") | ||
@GetMapping("") | ||
public ResponseEntity<List<ProductListOutput>> getAllProducts() { | ||
List<ProductListOutput> products = productService.getAllProducts(); | ||
return ResponseEntity.status(HttpStatus.OK).body(products); | ||
} | ||
|
||
@Operation(summary = "제품 ID로 조회") | ||
@GetMapping("/{id}") | ||
public ResponseEntity<ProductOutput> getProductById(@PathVariable Long id) { | ||
ProductOutput product = productService.getProductById(id); | ||
return ResponseEntity.status(HttpStatus.OK).body(product); | ||
} | ||
|
||
@Operation(summary = "새 제품 추가") | ||
@PostMapping("") | ||
public ResponseEntity<ProductOutput> createProduct(@RequestBody ProductInput productInput) { | ||
// 서비스 레이어를 통해 비즈니스 로직 처리 | ||
ProductOutput newProduct = productService.insertProduct(productInput); | ||
|
||
// 생성된 Product 객체 반환 | ||
return ResponseEntity.status(HttpStatus.CREATED).body(newProduct); | ||
} | ||
|
||
@Operation(summary = "제품 정보 업데이트") | ||
@PatchMapping("/{id}") | ||
public ResponseEntity<ProductOutput> updateProduct(@PathVariable Long id, @RequestBody ProductUpdate productDetails) { | ||
// 서비스 레이어를 통해 비즈니스 로직 처리 | ||
ProductOutput updatedProduct = productService.updateProduct(id, productDetails); | ||
|
||
// 업데이트된 Product 객체 반환 | ||
return ResponseEntity.ok().body(updatedProduct); | ||
} | ||
@Operation(summary = "제품 삭제") | ||
@DeleteMapping("/{id}") | ||
public ResponseEntity<ProductOutput> deleteProduct(@PathVariable Long id) { | ||
ProductOutput removedProduct = productService.removeProduct(id); | ||
return ResponseEntity.ok().body(removedProduct); | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
...-api/src/main/java/com/ssafy/springbootapi/domain/product/application/ProductService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package com.ssafy.springbootapi.domain.product.application; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import com.ssafy.springbootapi.domain.product.dao.ProductRepository; | ||
import com.ssafy.springbootapi.domain.product.domain.Product; | ||
import com.ssafy.springbootapi.domain.product.domain.ProductMapper; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductInput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductListOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductUpdate; | ||
import com.ssafy.springbootapi.domain.product.exception.NotFoundProductException; | ||
import com.ssafy.springbootapi.domain.user.dao.UserRepository; | ||
import com.ssafy.springbootapi.domain.user.domain.User; | ||
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 ProductMapper productMapper; | ||
|
||
|
||
/** | ||
* Product 전체 조회 | ||
* @return List(ProductListOutput) | ||
*/ | ||
public List<ProductListOutput> getAllProducts() { | ||
List<Product> products = productRepository.findAll(); | ||
return products.stream() | ||
.map(productMapper::toProductListOutput) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
/** | ||
* Product ID로 조회 | ||
* @param id : 조회할 상품 id | ||
* @return ProductOutput(DTO) | ||
*/ | ||
public ProductOutput getProductById(Long id) { | ||
Product product = findProductByIdOrThrow(id); | ||
return productMapper.toProductOutput(product); | ||
} | ||
|
||
/** | ||
* Product 삽입 메서드 | ||
* @param productInput : Product 생성 데이터 | ||
* @return ProductOutput(DTO) | ||
*/ | ||
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()) | ||
); | ||
|
||
// ProductInput에서 Product 엔티티로 변환 | ||
Product product = productMapper.toEntity(productInput); | ||
|
||
// User 객체를 Product 엔티티에 설정 | ||
product.setUser(user); | ||
|
||
// Product 엔티티를 DB에 저장하고, 저장된 엔티티를 ProductOutput DTO로 변환하여 반환 | ||
return productMapper.toProductOutput(productRepository.save(product)); | ||
} | ||
|
||
|
||
/** | ||
* Product 삭제 메서드 | ||
* @param id : 삭제할 product id | ||
* @return ProductOutput(DTO) | ||
*/ | ||
public ProductOutput removeProduct(Long id) { | ||
Product toRemove = findProductByIdOrThrow(id); | ||
productRepository.delete(toRemove); | ||
return productMapper.toProductOutput(toRemove); | ||
} | ||
|
||
/** | ||
* Product 수정 메서드 | ||
* @param id : 수정할 product id | ||
* @param productUpdate : 수정할 product 데이터 | ||
* @return ProductOutput(DTO) | ||
*/ | ||
@Transactional | ||
public ProductOutput updateProduct(Long id, ProductUpdate productUpdate) { | ||
Product productToUpdate = findProductByIdOrThrow(id); | ||
productMapper.updateProduct(productUpdate, productToUpdate); | ||
return productMapper.toProductOutput(productRepository.save(productToUpdate)); | ||
} | ||
|
||
/** | ||
* id로 product 찾기 또는 없을 경우 Exception 발생 | ||
* @param id : product id | ||
* @return Product(Entity) | ||
*/ | ||
private Product findProductByIdOrThrow(Long id) { | ||
return productRepository.findById(id) | ||
.orElseThrow(() -> new NotFoundProductException("Product not found with id: " + id)); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dao/ProductRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.ssafy.springbootapi.domain.product.dao; | ||
|
||
import com.ssafy.springbootapi.domain.product.domain.Product; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ProductRepository extends JpaRepository<Product, Long> { | ||
} |
66 changes: 66 additions & 0 deletions
66
spring-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/domain/Product.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.ssafy.springbootapi.domain.product.domain; | ||
|
||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.ssafy.springbootapi.domain.user.domain.User; | ||
import jakarta.persistence.*; | ||
import lombok.*; | ||
import org.springframework.data.annotation.CreatedDate; | ||
import org.springframework.data.annotation.LastModifiedDate; | ||
import org.springframework.data.jpa.domain.support.AuditingEntityListener; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Entity | ||
@EntityListeners(AuditingEntityListener.class) | ||
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}) | ||
@Table(name = "product") | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Getter | ||
@Setter | ||
@Builder | ||
public class Product { | ||
@Id | ||
@GeneratedValue | ||
@Column(name = "id", unique = true) | ||
private Long id; | ||
|
||
@Column(name = "image_url") | ||
private String imageUrl; | ||
|
||
@CreatedDate | ||
@Column(name = "created_at") | ||
private LocalDateTime createdAt; | ||
|
||
@LastModifiedDate | ||
@Column(name = "updated_at") | ||
private LocalDateTime updatedAt; | ||
|
||
@Column(name = "name", nullable = false) | ||
private String name; | ||
|
||
@Column(name = "price", nullable = false) | ||
private int price; | ||
|
||
@Column(name = "description", nullable = false) | ||
private String description; | ||
|
||
@Column(nullable = false) | ||
private int category; | ||
|
||
@Column(nullable = false) | ||
private int 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; | ||
this.stock = stock; | ||
this.imageUrl = imageUrl; | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...g-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/domain/ProductMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.ssafy.springbootapi.domain.product.domain; | ||
|
||
import com.ssafy.springbootapi.domain.product.dto.ProductInput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductListOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductOutput; | ||
import com.ssafy.springbootapi.domain.product.dto.ProductUpdate; | ||
import org.mapstruct.BeanMapping; | ||
import org.mapstruct.Mapper; | ||
import org.mapstruct.MappingTarget; | ||
import org.mapstruct.NullValuePropertyMappingStrategy; | ||
|
||
@Mapper(componentModel = "spring") | ||
public interface ProductMapper { | ||
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) | ||
void updateProduct(ProductUpdate dto, @MappingTarget Product entity); | ||
|
||
Product toEntity(ProductUpdate dto); | ||
Product toEntity(ProductInput dto); | ||
|
||
ProductOutput toProductOutput(Product entity); | ||
ProductListOutput toProductListOutput(Product entity); | ||
} |
14 changes: 14 additions & 0 deletions
14
spring-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dto/ProductBase.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.ssafy.springbootapi.domain.product.dto; | ||
|
||
import lombok.*; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Getter | ||
@SuperBuilder | ||
public class ProductBase { | ||
private String imageUrl; | ||
private String name; | ||
private int price; | ||
} |
18 changes: 18 additions & 0 deletions
18
spring-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dto/ProductInput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.ssafy.springbootapi.domain.product.dto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import lombok.*; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Getter | ||
@Setter | ||
@SuperBuilder | ||
public class ProductInput extends ProductBase { | ||
private String description; | ||
private int category; | ||
private int stock; | ||
@NotBlank(message = "user id is required") | ||
private Long user_id; | ||
} |
12 changes: 12 additions & 0 deletions
12
...-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dto/ProductListOutput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.ssafy.springbootapi.domain.product.dto; | ||
|
||
import lombok.*; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Getter | ||
@SuperBuilder | ||
public class ProductListOutput extends ProductBase{ | ||
private Long id; | ||
} |
18 changes: 18 additions & 0 deletions
18
spring-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dto/ProductOutput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.ssafy.springbootapi.domain.product.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Getter | ||
@SuperBuilder | ||
public class ProductOutput extends ProductListOutput{ | ||
private String description; | ||
private int category; | ||
private int stock; | ||
// private int user_id; | ||
} |
17 changes: 17 additions & 0 deletions
17
spring-boot-api/src/main/java/com/ssafy/springbootapi/domain/product/dto/ProductUpdate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.ssafy.springbootapi.domain.product.dto; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Getter | ||
@SuperBuilder | ||
public class ProductUpdate extends ProductBase { | ||
private String description; | ||
private int category; | ||
private int stock; | ||
} |
7 changes: 7 additions & 0 deletions
7
.../main/java/com/ssafy/springbootapi/domain/product/exception/NotFoundProductException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.ssafy.springbootapi.domain.product.exception; | ||
|
||
public class NotFoundProductException extends RuntimeException{ | ||
public NotFoundProductException(String message) { | ||
super(message); | ||
} | ||
} |
Oops, something went wrong.