일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- spring-boot
- 카카오
- S3
- Java
- 사물인식
- jwt
- 프로그래머스
- objectdetection
- 멋사
- EC2
- 파이썬 #백준 #BFS
- CRUD
- 인공지능
- 서류전형
- 면접전형
- 백준
- 파이썬
- nodejs
- AWS
- 멋쟁이사자처럼
- 합격후기
- 페이지네이션
- jQuery
- MongoDB
- Python
- 솝트 후기
- yolov5
- 피로그래밍
- 절차지향
- 솝트
- Today
- Total
찔끔찔끔씩😎
[웹개발의 봄, Spring] 4주차 (2) - <나만의 셀렉샵> 서버 본문
[웹개발의 봄, Spring] 4주차 (1) - 네이버 쇼핑 API 이용하기
프로젝트 만들기
🔎 프로젝트 시작시 확인할 점
1. Auto Import
- Inser imports on paste: Always'
2. Annotation Processing
- Compiler-Annotation Processors
🔎 API
키워드로 상품 검색하고 그 결과를 목록으로 보여주기 | GET | /api/search?query=검색어 | List<ItemDto> |
관심 상품 등록하기 | POST |
/api/products
|
Product |
관심 상품 조회하기
|
GET | /api/products | List<Product> |
관심 상품에 관심 가격 등록하고, 그 가격보다 낮은 경우 표시하기 | PUT | /api/products/{id} | id |
🔎 3계층
- Controller
- ProductRestController: 관심 상품 관련 컨트롤러
- SearchRequestController: 검색 관련 컨트롤러
- Service
- ProductService: 관심 상품 가격 변경
- Repository
- Product: 관심 상품 테이블
- ProductRepository: 관심 상품 조회, 저장
- ProductRequestDto: 관심 상품 등록하기
- ProductMypriceRequestDto: 관심 가격 변경하기
- ItemDto: 검색 결과 주고받기
위 계층에 유의하여 관심 상품 조회 -> 관심 상품 저장 -> 관심 상품 최저가 설정 순으로 기능을 구현해보도록 한다.
<나만의 셀렉샵> 서버
🔎 관심 상품 조회하기
[모아보기] 탭을 눌렀을 때 등록된 관심 상품을 조회할 수 있는 기능 !
그러기 위해선 관심 상품들을 데이터베이스에 모아두어야할 것이다.
1. Timestamped 만들기
관심상품(Product) 클래스를 만들어야 한다. 하지만 이전에 Product가 상속받을 Timestamped 클래스를 만들자.
1) week04/models/Timestamped 만들기
@Getter // get 함수를 자동 생성합니다.
@MappedSuperclass // 멤버 변수가 컬럼이 되도록 합니다.
@EntityListeners(AuditingEntityListener.class) // 변경되었을 때 자동으로 기록합니다.
public abstract class Timestamped { // abstract: 반드시 다른 곳에서 상속되어서 사용될 것!
@CreatedDate // 최초 생성 시점
private LocalDateTime createdAt;
@LastModifiedDate // 마지막 변경 시점
private LocalDateTime modifiedAt;
}
2) Week04Applications 에 시간 자동변경 어노테이션(AuditingEntityListener) 추가
이때 AuditingEntityListener를 사용하기 위해 Application에게 알려줘야 한다.
- @EnableJpaAuditing
@EnableJpaAuditing // 시간 자동 변경이 가능하도록 함
@SpringBootApplication
public class Week04Application {
public static void main(String[] args) {
SpringApplication.run(Week04Application.class, args);
}
}
2. Product 만들기
관심 상품 테이블에 저장해야 할 데이터는 title, image, link, lprice, myprice이다.
1) week04/models/Product 만들기
@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;
}
3. ProductRepository 만들기
Product 테이블을 만들었으니, Repository도 바로 만들어 준다.
1) models/ProductRepository 만들기
: Product 대상, Long 형태
public interface ProductRepository extends JpaRepository<Product, Long> {
}
4. ProductRestController 만들기
관심 상품에 관한 요청을 처리해줄 컨트롤러가 필요하다.
"관심 상품 조회"를 위해서는 그냥 productRepository에서 findAll 해주면 될 것 같다!
1) controller/ProductRestController 만들기
2)
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductRestController {
private final ProductRepository productRepository;
// 등록된 전체 상품 목록 조회
@GetMapping("/api/products")
public List<Product> getProducts() {
return productRepository.findAll();
}
}
🔎 관심 상품 등록하기
상품을 검색한 후, 등록 버튼을 눌렀을 때 관심 상품이 Repository에 생성되어야 한다.
검색 결과의 제목, 이미지, 링크, 최저가를 가져오기.
1. ProductRequestDto
- 위 네가지 정보를 가져가는 Dto를 먼저 만들어주자.
1) models/ProductRequesDto
@Getter
public class ProductRequestDto {
// title, link, image, lprice만 들고다니면 된다.
private String title;
private String link;
private String image;
private int lprice;
}
2. Product 클래스에 생성자를 만들어 주자.
ProductRequestDto를 만들었으니 이용해주는 게 인지상정!
Product 클래스에 ProductRequestDto 이용하는 생성자를 추가한다.
// 관심 상품 생성 시 이용할 생성자.
public Product(ProductRequestDto requestDto) {
this.title = requestDto.getTitle();
this.image = requestDto.getImage();
this.link = requestDto.getLink();
this.lprice = requestDto.getLprice();
this.myprice = 0;
}
3. ProductRestController 만들기
"관심 상품 등록" api를 추가해주자.
PostMapping으로 api요청을 받은 뒤 Dto를 Repository에 추가해주면 되겠다.
@PostMapping("/api/products")
public Product createProduct(@RequestBody ProductRequestDto requestDto){
// @RequestBody를 붙여주어야 함
Product product = new Product(requestDto);
return productRepository.save(product);
}
🔎 관심 상품 최저가 설정
"관심 상품의 관심 최저가를 등록하고, 가격이 이보다 낮아지는 경우 표기" 하는 기능 하나만 남았다.
관심 가격을 등록하려면 이 또한 DTO를 이용해야 된다.
ProductMypriceRequestDto를 만들어서 myprice를 갖도록 한다.
1. ProductMypriceRequestDto
- 본인이 설정한 최저가를 수정할 때 사용할, 가격정보만 들어있는 Dto
@Getter
public class ProductMypriceRequestDto {
private int myprice;
}
2. Product 클래스에도 update 만들기
myprice를 변경할 때 사용할 것!
// 수정시에 사용될 생성자
public void update(ProductMypriceRequestDto requestDto) {
this.myprice = requestDto.getMyprice();
}
3. ProductService 만들기
수정하기 위해서는 Service를 만들어주어야 한다.
관심상품의 id와 ProductMypriceRequestDto를 받아서 해당 상품의 myprice정보를 update 해주자!
예외 처리도 해주도록 한다.
+ 잊지말고 Transactional 어노테이션을 꼭 해준다!
@RequiredArgsConstructor // final로 선언된 멤버 변수가 꼭 필요함을 알려주기 위함.
@Service // 서비스임을 알려준다.
public class ProductService {
private final ProductRepository productRepository;
@Transactional // 메소드 동작이 SQL 쿼리문임을 알려준다.
public Long update(Long id, ProductMypriceRequestDto requestDto) {
// id에 해당되는 애를 업데이트
// productRepository에서 id에 해당되는 애를 findById
Product product = productRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 아이디가 존재하지 않습니다.")
);
product.update(requestDto);
return id;
}
}
🔎 + Scheduler
상품가격(lpice) 매일 업데이트 해주기. 그래야 최저가를 바꿔주지!
관심 상품 title을 검색한 뒤 해당 상품의 lprice를 매일 새벽 1시에 업데이트하는 스케줄러를 만들었다.
1. Scheduler 클래스 만들기
1) utils/Scheduler
@RequiredArgsConstructor // final 멤버 변수를 자동으로 생성합니다.
@Component // 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가합니다.
public class Scheduler {
private final ProductRepository productRepository;
private final ProductService productService;
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);
}
}
}
2. updateBySearch 함수 만들기
1) service/ProductService 에 추가하기
@Transactional // 메소드 동작이 SQL 쿼리문임을 선언.
public Long updateBySearch(Long id, ItemDto itemDto) {
Product product = productRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 아이디가 존재하지 않습니다.")
);
product.updateByItemDto(itemDto);
return id;
}
3. Application, @EnableScheduling
스프링부트가 스케줄러를 작동시키도록 Application에 @EnableScheduling을 추가한다.
@EnableScheduling // 스프링 부트에서 스케줄러가 작동하게 함
@EnableJpaAuditing // 시간 자동 변경이 가능하도록 합니다.
@SpringBootApplication // 스프링 부트임을 선언합니다.
public class Week04Application {
public static void main(String[] args) {
SpringApplication.run(Week04Application.class, args);
}
}
이로써 <나만의 셀렉샵>의 서버를 모두 완성했다! 이제 관련 클라이언트부분을 만들러 가보쟛~
상품명에 따른 검색관심 상품 등록, 조회관심 상품에 대한 최저가 등록, 조회
'Server > Spring' 카테고리의 다른 글
[웹개발의 봄, Spring] 4주차 (3) - <나만의 셀렉샵> 클라이언트 (0) | 2022.04.11 |
---|---|
[웹개발의 봄, Spring] 4주차 (1) - 네이버 쇼핑 API 이용하기 (0) | 2022.04.04 |
[Spring] spring jpa localtime between (0) | 2022.03.22 |
[웹개발의 봄, Spring] 3주차 (3) - 타임라인 서비스 클라이언트 완성하기 (0) | 2022.03.22 |
[웹개발의 봄, Spring] 3주차 (2) - javascript, jQuery 기초 (0) | 2022.03.19 |