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

[#13] Feat: Store #18

Merged
merged 7 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public class SecurityConfig {
"/api/auth/reissue"
};

private static final String[] AUTH_WHITELIST_WITH_BOARD = {
private static final String[] AUTH_WHITELIST_WITH_GET_METHOD = {
"/api/stores/**",
"/api/posts/**",
"/api/comments/**"
};
Expand Down Expand Up @@ -66,7 +67,7 @@ protected SecurityFilterChain config(HttpSecurity http) throws Exception {
.authorizeRequests(authorize -> authorize
.antMatchers(AUTH_WHITELIST_WITH_MEMBER_AUTH)
.permitAll()
.antMatchers(HttpMethod.GET, AUTH_WHITELIST_WITH_BOARD)
.antMatchers(HttpMethod.GET, AUTH_WHITELIST_WITH_GET_METHOD) // 인증 없이 조회 가능한 API 목록
.permitAll()
.anyRequest()
.authenticated()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package greeny.backend.domain.store.controller;

import greeny.backend.domain.store.service.StoreService;
import greeny.backend.response.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import static greeny.backend.response.Response.*;
import static greeny.backend.response.SuccessMessage.*;
import static org.springframework.http.HttpStatus.*;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/stores")
@Tag(name = "Store", description = "Store API Document")
public class StoreController {

private final StoreService storeService;

@Operation(summary = "Get simple store infos API", description = "please get simple store infos.")
@ResponseStatus(OK)
@GetMapping("/simple")
public Response getSimpleStoreInfosWithReview() {
return success(SUCCESS_TO_GET_SIMPLE_STORE_INFOS, storeService.getSimpleStoreInfosWithReview());
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package greeny.backend.domain.store.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import greeny.backend.domain.store.entity.Store;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class GetSimpleStoreInfosResponseDto { // 스토어 목록에 보여주는 정보

private Long id;
private String category;
private String name;
private String imageUrl;
private String location;
private int bookmarks; // 찜한 사람들의 수
private int reviews; // 리뷰 수

public static GetSimpleStoreInfosResponseDto from(Store store, int bookmarks, int reviews) {
return GetSimpleStoreInfosResponseDto.builder()
.id(store.getId())
.category(store.getCategory().getName())
.name(store.getName())
.imageUrl(store.getImageUrl())
.location(store.getLocation())
.bookmarks(bookmarks)
.reviews(reviews)
.build();
}
}
5 changes: 4 additions & 1 deletion src/main/java/greeny/backend/domain/store/entity/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.BatchSize;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static javax.persistence.CascadeType.ALL;

Expand All @@ -32,7 +35,7 @@ public class Store extends AuditEntity {
@OneToMany(mappedBy = "store", cascade = ALL, orphanRemoval = true)
private List<StoreReview> storeReviews = new ArrayList<>();
@OneToMany(mappedBy = "store", cascade = ALL, orphanRemoval = true)
private List<StoreBookmark> storeBookmarks = new ArrayList<>();
private Set<StoreBookmark> storeBookmarks = new HashSet<>();

@Enumerated(EnumType.STRING)
@Column(nullable = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
package greeny.backend.domain.store.repository;

import greeny.backend.domain.store.entity.Store;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface StoreRepository extends JpaRepository<Store, Long> {
@EntityGraph(attributePaths = {"storeReviews", "storeBookmarks"}) // Collection fetch join -> DB 과부하 방지를 위해 batch size 설정
@NotNull
List<Store> findAll();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package greeny.backend.domain.store.service;

import greeny.backend.domain.store.dto.GetSimpleStoreInfosResponseDto;
import greeny.backend.domain.store.repository.StoreRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class StoreService {

private final StoreRepository storeRepository;

public List<GetSimpleStoreInfosResponseDto> getSimpleStoreInfosWithReview() {
return storeRepository.findAll().stream()
.map(store -> GetSimpleStoreInfosResponseDto.from(store, store.getStoreBookmarks().size(), store.getStoreReviews().size()))
.collect(Collectors.toList());
}


}
4 changes: 3 additions & 1 deletion src/main/java/greeny/backend/response/SuccessMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ public class SuccessMessage {
public static final String SUCCESS_TO_FIND_PASSWORD = "비밀번호를 찾는데 성공했습니다.";
public static final String SUCCESS_TO_REISSUE = "토큰 재발급에 성공했습니다.";

public static final String SUCCESS_TO_GET_CURRENT_MEMBER_INFO = "현재 회원의 정보를 가져오는데 성공했습니다.";
public static final String SUCCESS_TO_DELETE_MEMBER = "회원을 삭제하는데 성공했습니다.";

public static final String SUCCESS_TO_GET_SIMPLE_STORE_INFOS = "스토어 목록을 불러오는데 성공했습니다.";
public static final String SUCCESS_TO_GET_STORE_INFO = "스토어 상세 정보를 불러오는데 성공했습니다.";

public static final String SUCCESS_TO_WRITE_POST = "게시글을 작성하는데 성공하였습니다.";
public static final String SUCCESS_TO_GET_POST_LIST = "게시글 목록을 불러오는데 성공하였습니다.";
public static final String SUCCESS_TO_SEARCH_POST_LIST = "게시글 목록을 검색하는데 성공하였습니다.";
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ spring:
properties:
hibernate:
format_sql: true
default_batch_fetch_size: 100 # Collection fetch join 시 100개씩 순차적으로 리스트를 불러옴 (DB 과부하 방지)
Minuooooo marked this conversation as resolved.
Show resolved Hide resolved
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
database: mysql
Expand Down