diff --git a/README.md b/README.md
index 2d08eab..b00dddb 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,15 @@
# BE
+
+
tech stack
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index c78b6e4..544c347 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,6 +58,10 @@ dependencies {
// Spring Batch
implementation 'org.springframework.boot:spring-boot-starter-batch'
testImplementation 'org.springframework.batch:spring-batch-test'
+
+ //h2
+ testImplementation 'com.h2database:h2'
+
}
tasks.named('test') {
diff --git a/src/main/java/com/github/commerce/config/batch/UpdateCustomerGradeScheduler.java b/src/main/java/com/github/commerce/config/batch/UpdateCustomerGradeScheduler.java
index 22dda67..ce814a3 100644
--- a/src/main/java/com/github/commerce/config/batch/UpdateCustomerGradeScheduler.java
+++ b/src/main/java/com/github/commerce/config/batch/UpdateCustomerGradeScheduler.java
@@ -23,8 +23,7 @@ public class UpdateCustomerGradeScheduler { //매월 1일 오전 12:00:00 구매
@Autowired
private Job updateCustomerGradeJob;
- //TODO. 일단은 매일 오전 12시로 해놓고 시연할 때는 30초로 간격 줄이기
- @Scheduled(cron = "*/10 * * * * *", zone = "Asia/Seoul") //초 분 시 일 월 요일 (*: 매번) - 매월 1일 오전 12:00:00 구매 금액에 따른 회원 등급 조정
+ @Scheduled(cron = "0 0 0 1 * *", zone = "Asia/Seoul") //초 분 시 일 월 요일 (*: 매번) - 매월 1일 오전 12:00:00 구매 금액에 따른 회원 등급 조정
public void updateCustomerGradeJobRun() throws JobInstanceAlreadyCompleteException, JobExecutionAlreadyRunningException, JobParametersInvalidException, JobRestartException {
JobParameters jobParameters = new JobParameters(
diff --git a/src/main/java/com/github/commerce/config/security/WebSecurityConfig.java b/src/main/java/com/github/commerce/config/security/WebSecurityConfig.java
index 810844e..b74b698 100644
--- a/src/main/java/com/github/commerce/config/security/WebSecurityConfig.java
+++ b/src/main/java/com/github/commerce/config/security/WebSecurityConfig.java
@@ -34,7 +34,7 @@ public class WebSecurityConfig {
private final JwtUtil jwtUtil;
private final UserDetailsServiceImpl userDetailsService;
private static final String[] PERMIT_URL_ARRAY = {
- "/","/v1/api/user/**","/v1/api/product/**","/v1/api/coupon","/GuerrillaCommerce",
+ "/","/v1/api/user/**","/v1/api/product/**","/v1/api/coupon","/GuerrillaCommerce", "/v1/api/navi",
"/api/v2/**", "/swagger-ui.html", "/swagger/**","/swagger-resources/**", "/webjars/**", "/v2/api-docs"
};
diff --git a/src/main/java/com/github/commerce/entity/Product.java b/src/main/java/com/github/commerce/entity/Product.java
index 19faa7a..67544e7 100644
--- a/src/main/java/com/github/commerce/entity/Product.java
+++ b/src/main/java/com/github/commerce/entity/Product.java
@@ -1,5 +1,6 @@
package com.github.commerce.entity;
+import com.github.commerce.web.dto.product.GetProductDto;
import com.github.commerce.web.dto.product.ProductRequest;
import com.google.gson.Gson;
import lombok.*;
@@ -17,6 +18,24 @@
@AllArgsConstructor
@Builder
@Entity
+@SqlResultSetMapping(
+ name = "GetProductDtoMapping",
+ classes = @ConstructorResult(
+ targetClass = GetProductDto.class,
+ columns = {
+ @ColumnResult(name = "id", type = Long.class),
+ @ColumnResult(name = "name", type = String.class),
+ @ColumnResult(name = "price", type = Integer.class),
+ @ColumnResult(name = "created_at", type = LocalDateTime.class),
+ @ColumnResult(name = "product_category", type = String.class),
+ @ColumnResult(name = "age_category", type = String.class),
+ @ColumnResult(name = "gender_category", type = String.class),
+ @ColumnResult(name = "left_amount", type = Integer.class),
+ @ColumnResult(name = "thumbnail_url", type = String.class),
+ @ColumnResult(name = "shop_name", type = String.class)
+ }
+ )
+)
@Table(name = "products")
public class Product {
@Id
diff --git a/src/main/java/com/github/commerce/repository/product/ProductRepositoryCustom.java b/src/main/java/com/github/commerce/repository/product/ProductRepositoryCustom.java
new file mode 100644
index 0000000..af06ae6
--- /dev/null
+++ b/src/main/java/com/github/commerce/repository/product/ProductRepositoryCustom.java
@@ -0,0 +1,241 @@
+package com.github.commerce.repository.product;
+
+import com.github.commerce.web.dto.product.GetProductDto;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Repository;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import java.util.List;
+
+@Repository
+public class ProductRepositoryCustom {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ public List findByProductCategorySortByCreatedAt(
+ String inputProductCategory,
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE p.product_category = :inputProductCategory " +
+ "AND (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.created_at DESC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputProductCategory", inputProductCategory);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List findByProductCategorySortByPrice(
+ String inputProductCategory,
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE p.product_category = :inputProductCategory " +
+ "AND (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.price ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputProductCategory", inputProductCategory);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List findByProductCategorySortById(
+ String inputProductCategory,
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE p.product_category = :inputProductCategory " +
+ "AND (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.id ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputProductCategory", inputProductCategory);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List findAllSortByCreatedAt(
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.created_at DESC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List findAllSortByPrice(
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.price ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List findAllSortById(
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "ORDER BY p.id ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+ public List searchProductSortByPrice(
+ String searchToken,
+ String inputAgeCategory,
+ String inputGenderCategory,
+ Pageable pageable) {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "AND p.name LIKE :searchToken " +
+ "ORDER BY p.price ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("searchToken", searchToken);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+ }
+
+
+ public List searchProductSortByCreatedAt(String searchToken, String inputAgeCategory, String inputGenderCategory, Pageable pageable)
+ {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "AND p.name LIKE :searchToken " +
+ "ORDER BY p.created_at DESC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("searchToken", searchToken);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+
+ }
+
+ public List searchProductSortById(String searchToken, String inputAgeCategory, String inputGenderCategory, Pageable pageable) {
+ String sql = "SELECT p.id, p.name, p.price, p.created_at, " +
+ "p.product_category, p.age_category, p.gender_category, " +
+ "p.left_amount, p.thumbnail_url, s.shop_name " +
+ "FROM commerce.products p LEFT JOIN commerce.sellers s ON p.sellers_id = s.id " +
+ "WHERE (:inputAgeCategory IS NULL OR p.age_category = :inputAgeCategory) " +
+ "AND (:inputGenderCategory IS NULL OR p.gender_category = :inputGenderCategory) " +
+ "AND p.is_deleted = false " +
+ "AND p.name LIKE :searchToken " +
+ "ORDER BY p.id ASC";
+
+ Query query = entityManager.createNativeQuery(sql, "GetProductDtoMapping");
+ query.setParameter("searchToken", searchToken);
+ query.setParameter("inputAgeCategory", inputAgeCategory);
+ query.setParameter("inputGenderCategory", inputGenderCategory);
+ query.setFirstResult((int) pageable.getOffset());
+ query.setMaxResults(pageable.getPageSize());
+
+ //noinspection unchecked
+ return query.getResultList();
+
+ }
+}
diff --git a/src/main/java/com/github/commerce/service/cart/CartService.java b/src/main/java/com/github/commerce/service/cart/CartService.java
index ff5adbb..6b289bf 100644
--- a/src/main/java/com/github/commerce/service/cart/CartService.java
+++ b/src/main/java/com/github/commerce/service/cart/CartService.java
@@ -4,7 +4,6 @@
import com.github.commerce.entity.Product;
import com.github.commerce.entity.User;
import com.github.commerce.repository.cart.CartRepository;
-import com.github.commerce.repository.product.ProductRepository;
import com.github.commerce.service.cart.util.ValidatCartMethod;
import com.github.commerce.web.dto.cart.CartDto;
import com.github.commerce.web.dto.cart.CartRmqDto;
@@ -21,9 +20,6 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -36,7 +32,6 @@ public class CartService {
private final CartRepository cartRepository;
private final ValidatCartMethod validatCartMethod;
private final RabbitTemplate rabbitTemplate;
- private final ProductRepository productRepository;
@Transactional(readOnly = true)
public List