Skip to content

Commit

Permalink
Feature/카테고리 상세 조회 및 브랜드&상품 조회 로직 일부 (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
YeaChan05 authored Mar 5, 2024
2 parents effd934 + 0ebfbfe commit 2c35951
Show file tree
Hide file tree
Showing 41 changed files with 2,462 additions and 304 deletions.
4 changes: 0 additions & 4 deletions src/main/java/org/kakaoshare/backend/BackEndApplication.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package org.kakaoshare.backend;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class BackEndApplication {
@Autowired
private TestComponent testComponent;

public static void main(String[] args) {
SpringApplication.run(BackEndApplication.class, args);
}
Expand Down
10 changes: 0 additions & 10 deletions src/main/java/org/kakaoshare/backend/TestComponent.java

This file was deleted.

14 changes: 0 additions & 14 deletions src/main/java/org/kakaoshare/backend/TestEntity.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.kakaoshare.backend.common.config;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.kakaoshare.backend.domain.brand.entity.Brand;
import org.kakaoshare.backend.domain.category.entity.Category;
import org.kakaoshare.backend.domain.category.repository.CategoryRepository;
import org.kakaoshare.backend.domain.product.entity.Product;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Random;

@Component
@Profile("dev")
@RequiredArgsConstructor
public class DatabaseInitializer {
private final CategoryRepository categoryRepository;

@PostConstruct
@Transactional
public void initDatabase() {
createParentCategories(5);
}

private void createParentCategories(final int count) {
for (int i = 0; i < count; i++) {
Category parent =Category
.builder()
.name("Parent Category " + (i+1))
.children(new ArrayList<>())
.build();
createChildCategories(parent, 5);
categoryRepository.save(parent);
}
}

private void createChildCategories(Category parent,final int count) {
for (int i = 0; i < count; i++) {
Category child = Category.builder()
.name("Child Category " + (i + 1))
.parent(parent)
.children(new ArrayList<>())
.brands(new ArrayList<>())
.build();
parent.getChildren().add(child);
createBrands(child, 5);
}
}

private void createBrands(Category category,final int count) {
for (int i = 0; i < count; i++) {
Brand brand = Brand
.builder()
.name(category.getName()+" Brand " + (i + 1))
.category(category)
.products(new ArrayList<>())
.build();
createProducts(brand, 10);
category.getBrands().add(brand);
}
}

private void createProducts(Brand brand,final int count) {
Random random = new Random();
for (int i = 0; i < count; i++) {
int price = 1000 + (random.nextInt(200) * 100);
Product product = Product.builder()
.name(brand.getName()+" Product " + (i + 1))
.price(BigDecimal.valueOf(price))
.brand(brand)
.wishes(new ArrayList<>())
.type("type"+(i+1))
.build();
brand.getProducts().add(product);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuerydslConfiguration {
public class QuerydslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kakaoshare.backend.common.config;

import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand All @@ -18,7 +19,8 @@
public class SecurityConfig {
private static final String ORIGIN_PATTERN = "*";
private static final String CORS_CONFIGURATION_PATTERN = "/**";

public static final String API_V_1 = "/api/v1/";

@Bean
public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
http.httpBasic().disable()
Expand All @@ -27,8 +29,13 @@ public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception
.and()
.authorizeHttpRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.requestMatchers(API_V_1 + "categories/**").permitAll()
.requestMatchers(API_V_1+"products/**").permitAll()
.requestMatchers(PathRequest.toH2Console()).permitAll()//TODO 2024 03 02 19:39:16 : 개발단계 이후 제거 요망
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable()
.and()
.cors();

return http.build();
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/kakaoshare/backend/common/util/OrderByNull.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.kakaoshare.backend.common.util;

import com.querydsl.core.types.NullExpression;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;

public class OrderByNull extends OrderSpecifier {

private static final OrderByNull DEFAULT = new OrderByNull();

private OrderByNull() {
super(Order.ASC, NullExpression.DEFAULT, NullHandling.Default);
}

public static OrderByNull getDefault() {
return OrderByNull.DEFAULT;
}
}
78 changes: 78 additions & 0 deletions src/main/java/org/kakaoshare/backend/common/util/SortUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.kakaoshare.backend.common.util;

import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.ComparableExpressionBase;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static org.kakaoshare.backend.domain.product.entity.QProduct.product;
import static org.springframework.data.domain.Sort.Order;

/**
* {@link SortableRepository#getOrderSpecifiers(Pageable)}를 구현할 때 기본조건을 제외한 정렬 조건을 {@link #from(Pageable)}로 지정해준다
* 필요한 정렬 조건을 열거체에 추가하여 사용하시면 됩니다
* 기본 정렬 조건은 각각의 Repository에서 따로 추가하도록 {@link OrderByNull}을 사용하였고,
* {@link #from(Pageable)} 뒤에 기본 정렬 조건을 {@link #from(Pageable)}와 합쳐 반환해 {@link com.querydsl.core.support.QueryBase#orderBy(OrderSpecifier)}에 주입하시면 됩니다
* 기본 정렬 조건이 가장 마지막에 들어가야합니다
*
* @author sin-yechan
* @see org.kakaoshare.backend.common.util.SortableRepository
*/
public enum SortUtil {
PRICE(product.price),
WISH_COUNT(product.wishes.size()),
PRODUCT_NAME(product.name);

private final ComparableExpressionBase<?> expression;

SortUtil(final ComparableExpressionBase<?> expression) {
this.expression = expression;
}


/**
* @param pageable {@link Pageable}
* @return 정렬 조건이 담긴 {@link OrderSpecifier} 배열
*/
public static OrderSpecifier<?>[] from(Pageable pageable) {
List<OrderSpecifier<?>> orderSpecifiers = new ArrayList<>();
if (pageable.getSort().isEmpty()) {
return new OrderByNull[]{OrderByNull.getDefault()};
}
pageable.getSort().forEach(order -> {
String property = order.getProperty().toUpperCase();
try {
SortUtil sortUtil = valueOf(property);
orderSpecifiers.add(sortUtil.getOrderSpecifiers(order));
} catch (IllegalArgumentException e) {
//TODO 2024 02 28 18:34:33 : 주어진 속성에 대한 정렬 순서가 열거형에 정의되어 있지 않은 경우
}
});


return orderSpecifiers.toArray(OrderSpecifier[]::new);
}

private OrderSpecifier<?> getOrderSpecifiers(final Order order) {
if (order.getDirection().isAscending()) {
return expression.asc();
}
return expression.desc();
}

public static void checkSortCondition(Pageable pageable) {
if(pageable.getSort().get().findAny().isEmpty())
return;
Arrays.stream(values())
.map(Enum::name)
.filter(s -> !pageable.getSort().isEmpty())
.filter(s -> Objects.nonNull(pageable.getSort().getOrderFor(s)))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("정렬 조건이 맞지 않습니다!"));
//TODO 2024 03 04 20:00:28 : 정렬 조건이 맞지 않은 경우 예외 처리 구체화
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.kakaoshare.backend.common.util;

import com.querydsl.core.types.OrderSpecifier;
import org.springframework.data.domain.Pageable;

/**
* @implNote 정렬이 필요한 Repository 구현체에 사용
* @author sin-yechan
*/
public interface SortableRepository {
OrderSpecifier<?>[] getOrderSpecifiers(final Pageable pageable);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kakaoshare.backend.domain.brand.entity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
Expand All @@ -9,15 +10,23 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import java.util.List;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.kakaoshare.backend.domain.base.entity.BaseTimeEntity;
import org.kakaoshare.backend.domain.category.entity.Category;
import org.kakaoshare.backend.domain.product.entity.Product;

import java.util.List;


@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Builder
public class Brand extends BaseTimeEntity {

@Id
Expand All @@ -34,7 +43,7 @@ public class Brand extends BaseTimeEntity {
@JoinColumn(name = "category_id")
private Category category;

@OneToMany(mappedBy = "brand")
@OneToMany(mappedBy = "brand",fetch = FetchType.LAZY,cascade = CascadeType.ALL)
private List<Product> products;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.kakaoshare.backend.domain.brand.entity.query;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;


@Getter
@Setter
@ToString
@NoArgsConstructor
public class SimpleBrandDto {
private Long brandId;
private String name;
private String iconPhoto;

@QueryProjection
public SimpleBrandDto(final Long brandId, final String name, final String iconPhoto) {
this.brandId = brandId;
this.name = name;
this.iconPhoto = iconPhoto;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.kakaoshare.backend.domain.brand.repository;

import org.kakaoshare.backend.domain.brand.entity.Brand;
import org.kakaoshare.backend.domain.brand.repository.query.BrandRepositoryCustom;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface BrandRepository extends JpaRepository<Brand, Long> {

public interface BrandRepository extends JpaRepository<Brand, Long> , BrandRepositoryCustom {
List<Brand> findByCategory_CategoryId(Long categoryId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.kakaoshare.backend.domain.brand.repository.query;

import org.kakaoshare.backend.domain.brand.entity.query.SimpleBrandDto;

import java.util.List;

public interface BrandRepositoryCustom {
List<SimpleBrandDto> findAllSimpleBrandByChildId(Long categoryId);

List<SimpleBrandDto> findAllSimpleBrandByParentId(Long categoryId);
}
Loading

0 comments on commit 2c35951

Please sign in to comment.