프로젝트 설계하기
필요 기능
- 키워드로 상품 검색하고 그 결과를 목록으로 보여주기
- 관심 상품 등록하기
- 관심 상품 조회하기
- 관심 상품에 원하는 가격 등록하고, 그 가격보다 낮은 경우 표시하기
API 설계
기능 | Method | URL | 반환 |
키워드로 상품 검색하고 그 결과를 목록으로 보여주기 | GET | /api/search?query=검색어 | List<ItemDto> |
관심 상품 등록하기 | POST | /api/products | Product |
관심 상품 조회하기 | GET | /api/products | List<ItemDto> |
관심 상품에 원하는 가격 등록하고, 그 가격보다 낮은 경우 표시하기 | PUT | /api/products/{id} | id |
3계층 설계
- Controller
- ProductRestController: 관심 상품 관련 컨트롤러
- SearchRequestController: 검색 관련 컨트롤러
- Service
- ProductService: 관심 상품 가격 변경
- Repository
- Product: 관심 상품 테이블
- ProductRepository: 관심 상품 조회, 저장
- ProductRequestDto: 관심 상품 등록
- ProductMypriceRequestDto: 관심 가격 변경
- ItemDto: 검색 결과 주고받기
관심 상품 조회
요구 조건
- "모아보기" 탭 클릭 시, 등록된 관심 상품 조회 기능
- Timestamped.java 생성 ( + Week04Application에 @EnableJpaAuditing 추가하여 시간 자동 변경이 가능하도록 설정)
@Getter // get 함수 자동 생성 @MappedSuperclass // 멤버 변수가 컬럼이 되도록 함 @EntityListeners(AuditingEntityListener.class) // 변경시 자동 기록 public abstract class Timestamped { @CreatedDate // 최초 생성 시점 private LocalDateTime createdAt; @LastModifiedDate // 마지막 변경 시점 private LocalDateTime modifiedAt; }
- Product.java 생성 (title, image, link, lprice, myprice 정보 필요)
@Getter // get 함수 일괄 생성 @NoArgsConstructor // 기본 생성자 생성 @Entity // DB 테이블 역할 public class Product extends Timestamped{ // ID 자동 생성 및 증가 @GeneratedValue(strategy = GenerationType.AUTO) @Id private Long id; // 반드시 값을 가지도록 함 @Column(nullable = false) private String title; @Column(nullable = false) private String image; @Column(nullable = false) private String link; @Column(nullable = false) private int lprice; @Column(nullable = false) private int myprice; }
- ProductRepository.java
public interface ProductRepository extends JpaRepository<Product, Long> { }
- ProductRestController.java
@RequiredArgsConstructor // final 로 선언된 멤버 변수 자동 생성 @RestController // JSON 으로 데이터 주고받음 선언 public class ProductRestController { private final ProductRepository productRepository; // 등록된 전체 상품 목록 조회 @GetMapping("/api/products") public List<Product> getProducts() { return productRepository.findAll(); } }
관심 상품 등록
요구 조건
- 상품을 검색한 후, 등록 버튼 클릭시 관심 상품 생성되어야 함
- 검색 결과에서 제목, 이미지, 링크, 최저가 가져오기
- ProductRequestDto.java 생성
@Getter public class ProductRequestDto { private String title; private String link; private String image; private int lprice; }
- ProductMypriceRequestDto.java 생성(관심 가격 등록 - 최저가)
@Getter public class ProductMypriceRequestDto { private int myprice; }
- Product.java에 생성자 추가
// 관심 상품 생성 시 이용 public Product(ProductRequestDto requestDto) { this.title = requestDto.getTitle(); this.image = requestDto.getImage(); this.link = requestDto.getLink(); this.lprice = requestDto.getLprice(); this.myprice = 0; } // 관심 가격 변경 시 이용 public void update(ProductMypriceRequestDto requestDto) { this.myprice = requestDto.getMyprice(); }
- ProductService.java 생성
@RequiredArgsConstructor // final 로 선언된 멤버 변수 자동 생성 @Service // 서비스임 선언 public class ProductService { private final ProductRepository productRepository; @Transactional // 메소드 동작이 SQL 쿼리문임 선언 public Long update(Long id, ProductMypriceRequestDto requestDto) { Product product = productRepository.findById(id).orElseThrow( () -> new NullPointerException("해당 아이디가 존재하지 않습니다.") ); product.update(requestDto); return id; } }
- ProductRestController.java에 신규 상품 등록 API 추가 (POST 방식)
@RequiredArgsConstructor // final 로 선언된 멤버 변수 자동 생성 @RestController // JSON 으로 데이터 주고받음 선언 public class ProductRestController { private final ProductRepository productRepository; private final ProductService productService; // 등록된 전체 상품 목록 조회 @GetMapping("/api/products") public List<Product> getProducts() { return productRepository.findAll(); } // 신규 상품 등록 @PostMapping("/api/products") public Product createProduct(@RequestBody ProductRequestDto requestDto) { Product product = new Product(requestDto); productRepository.save(product); return product; } }
최저가 변경
- ProductRestController.java에 최저가 변경 API 추가 (PUT 방식)
// 설정 가격 변경 @PutMapping("/api/products/{id}") public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) { return productService.update(id, requestDto); }
Scheduler
- 매일 새벽 1시에 관심 상품 목록 제목으로 검색하여 최저가 정보를 업데이트
- src > main > java > com.sparta.week04 > utils 에 Scheduler.java 파일 생성
@RequiredArgsConstructor // final 로 선언된 멤버 변수 자동 생성 @Component // 스프링이 필요시 자동으로 생성하는 클래스 목록에 추가 public class Scheduler { private final ProductService productService; private final ProductRepository productRepository; private final NaverShopSearch naverShopSearch; // 초, 분, 시, 일, 월, 주 순서 @Scheduled(cron = "0 0 1 * * *") public void updatePrice() throws InterruptedException { System.out.println("가격 업데이트 실행"); // 저장된 모든 관심상품을 조회합니다. List<Product> productList = productRepository.findAll(); for (int i = 0; i < productList.size(); i++) { // 1초에 한 상품 씩 조회합니다 (Naver 제한) TimeUnit.SECONDS.sleep(1); // i 번째 관심 상품을 꺼냅니다. Product p = productList.get(i); // i 번째 관심 상품의 제목으로 검색을 실행합니다. String title = p.getTitle(); String resultString = naverShopSearch.search(title); // i 번째 관심 상품의 검색 결과 목록 중에서 첫 번째 결과를 꺼냅니다. List<ItemDto> itemDtoList = naverShopSearch.fromJSONtoItems(resultString); ItemDto itemDto = itemDtoList.get(0); // i 번째 관심 상품 정보를 업데이트합니다. Long id = p.getId(); productService.updateBySearch(id, itemDto); } } }
- ProductService.java 에 내용 추가하기
@Transactional // 메소드 동작이 SQL 쿼리문임 선언 public Long updateBySearch(Long id, ItemDto itemDto) { Product product = productRepository.findById(id).orElseThrow( () -> new NullPointerException("해당 아이디가 존재하지 않습니다.") ); product.updateByItemDto(itemDto); return id; }
- Product.java 에 내용 추가하기
// 최저가 변경 시 이용 public void updateByItemDto(ItemDto itemDto) { this.lprice = itemDto.getLprice(); }
- Week04Application.java 에 @EnableScheduling 추가하여 스프링 부트에서 스케줄러가 작동하게 함
'Spring' 카테고리의 다른 글
[Spring] 나만의 셀렉샵 프로젝트 - 배포(AWS RDS, EC2, MySQL, Filezilla, Port Forwarding) (0) | 2024.07.31 |
---|---|
[Spring] 나만의 셀렉샵 프로젝트 - 클라이언트(HTML, Javascript, jQuery, CSS) (0) | 2024.07.30 |
[Spring] 나만의 셀렉샵 프로젝트 - 네이버 쇼핑 API 이용(API, Spring MVC, JPA) (0) | 2024.07.29 |
[Spring] 타임라인 서비스 프로젝트 - 클라이언트(HTML, Javascript, jQuery) (0) | 2024.07.24 |
[Spring] 타임라인 서비스 프로젝트 - 서버(API 설계/ Spring MVC/ JPA) (0) | 2024.07.23 |