-
Notifications
You must be signed in to change notification settings - Fork 2
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
Release 1.2.0 #92
base: develop
Are you sure you want to change the base?
Release 1.2.0 #92
Changes from 10 commits
8e6b29a
4f8c797
53b184b
03dd18c
928e65f
96390ec
e9dcfa5
4e9cd80
2b52350
f35ad5e
c0db490
4cef932
3ca7b66
0529d07
33b2dce
6ee6d78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,22 @@ | ||
package com.example.flab.soft.shoppingmallfashion.common; | ||
|
||
import java.time.Duration; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.cache.CacheManager; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.data.redis.cache.RedisCacheConfiguration; | ||
import org.springframework.data.redis.cache.RedisCacheManager; | ||
import org.springframework.data.redis.connection.RedisConnectionFactory; | ||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; | ||
import org.springframework.data.redis.core.RedisTemplate; | ||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; | ||
import org.springframework.data.redis.serializer.RedisSerializationContext; | ||
import org.springframework.data.redis.serializer.StringRedisSerializer; | ||
import org.springframework.orm.jpa.JpaTransactionManager; | ||
import org.springframework.transaction.PlatformTransactionManager; | ||
|
||
@Configuration | ||
public class RedisConfig { | ||
|
@@ -35,6 +45,32 @@ public RedisTemplate<String, Object> redisTemplate() { | |
|
||
redisTemplate.setDefaultSerializer(new StringRedisSerializer()); | ||
|
||
redisTemplate.setEnableTransactionSupport(true); | ||
|
||
return redisTemplate; | ||
} | ||
|
||
@Bean | ||
public CacheManager cacheManager() { | ||
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig() | ||
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) | ||
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); | ||
|
||
Map<String, RedisCacheConfiguration> redisCacheConfigMap = new HashMap<>(); | ||
redisCacheConfigMap.put("ITEM_LIST", defaultConfig.entryTtl(Duration.ofMinutes(10))); | ||
redisCacheConfigMap.put("ITEM_DETAILS", defaultConfig.entryTtl(Duration.ofDays(1))); | ||
redisCacheConfigMap.put("ITEM_LIST_COUNT", defaultConfig.entryTtl(Duration.ofDays(1))); | ||
redisCacheConfigMap.put("TOP_ITEMS_STORE", defaultConfig.entryTtl(Duration.ofMinutes(10))); | ||
redisCacheConfigMap.put("TOP_ITEMS_CATEGORY", defaultConfig.entryTtl(Duration.ofMinutes(10))); | ||
redisCacheConfigMap.put("STOCKS", defaultConfig.entryTtl(Duration.ofMinutes(10))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 하면 모든 캐시에 적용되는데 ttl 설정을 추가하신 이유가 있을까요?? |
||
|
||
return RedisCacheManager.builder(redisConnectionFactory()) | ||
.withInitialCacheConfigurations(redisCacheConfigMap) | ||
.build(); | ||
} | ||
|
||
@Bean | ||
public PlatformTransactionManager transactionManager() { | ||
return new JpaTransactionManager(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
import com.example.flab.soft.shoppingmallfashion.item.domain.Sex; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import org.springframework.cache.annotation.Cacheable; | ||
import org.springframework.data.domain.Page; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
@@ -14,30 +15,47 @@ public interface ItemRepository extends JpaRepository<Item, Long> { | |
@Query("SELECT i FROM items i JOIN FETCH i.store s " + | ||
"JOIN FETCH i.category c JOIN FETCH c.largeCategory lc " | ||
+ "WHERE " + | ||
"(:storeId IS NULL OR i.store.id = :storeId) AND " + | ||
"(:categoryId IS NULL OR i.category.id = :categoryId) AND " + | ||
"(:minPrice IS NULL OR i.salePrice >= :minPrice) AND " + | ||
"(:maxPrice IS NULL OR i.salePrice <= :maxPrice) AND " + | ||
"(:categoryId IS NULL OR i.category.id = :categoryId) AND " + | ||
"(:storeId IS NULL OR i.store.id = :storeId) AND " + | ||
"(:sex IS NULL OR i.sex = :sex) AND " + | ||
"i.saleState IN ('ON_SALE', 'TEMPORARILY_SOLD_OUT')") | ||
Page<Item> findAllByFilters(@Param("minPrice") Integer minPrice, | ||
List<Item> findAllByFilters(@Param("minPrice") Integer minPrice, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. QueryDsl 적용해서 동적쿼리 만들어주세요 (:minPrice IS NULL OR i.salePrice >= :minPrice) |
||
@Param("maxPrice") Integer maxPrice, | ||
@Param("categoryId") Long categoryId, | ||
@Param("storeId") Long storeId, | ||
@Param("sex") Sex sex, | ||
Pageable pageable); | ||
|
||
@Query("SELECT COUNT (i) FROM items i WHERE " + | ||
"(:minPrice IS NULL OR i.salePrice >= :minPrice) AND " + | ||
"(:maxPrice IS NULL OR i.salePrice <= :maxPrice) AND " + | ||
"(:categoryId IS NULL OR i.category.id = :categoryId) AND " + | ||
"(:storeId IS NULL OR i.store.id = :storeId) AND " + | ||
"(:sex IS NULL OR i.sex = :sex) AND " + | ||
"i.saleState IN ('ON_SALE', 'TEMPORARILY_SOLD_OUT')") | ||
Long countByFilters(@Param("minPrice") Integer minPrice, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. count 쿼리도 querydsl로 처리해주세요 |
||
@Param("maxPrice") Integer maxPrice, | ||
@Param("categoryId") Long categoryId, | ||
@Param("storeId") Long storeId, | ||
@Param("sex") Sex sex); | ||
|
||
@Query("SELECT i FROM items i JOIN FETCH i.store s " | ||
+ "JOIN FETCH i.category c JOIN FETCH c.largeCategory lc " | ||
+ "JOIN FETCH i.itemOptions io " | ||
+ "WHERE i.id = :id") | ||
Optional<Item> findItemJoinFetchById(Long id); | ||
|
||
@Query("SELECT i FROM items i WHERE i.category.id = :categoryId " | ||
@Query("SELECT i FROM items i JOIN FETCH i.store s " | ||
+ "JOIN FETCH i.category c JOIN FETCH c.largeCategory lc " | ||
+ "WHERE i.category.id = :categoryId " | ||
+ "ORDER BY i.itemStats.orderCount DESC") | ||
List<Item> findTopItemsByCategoryId(Long categoryId, Pageable pageable); | ||
|
||
@Query("SELECT i FROM items i WHERE i.store.id = :storeId " | ||
@Query("SELECT i FROM items i JOIN FETCH i.store s " | ||
+ "JOIN FETCH i.category c JOIN FETCH c.largeCategory lc " | ||
+ "WHERE i.store.id = :storeId " | ||
+ "ORDER BY i.itemStats.orderCount DESC") | ||
List<Item> findTopItemsByStoreId(Long storeId, Pageable pageable); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.example.flab.soft.shoppingmallfashion.item.service; | ||
|
||
import java.util.List; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
@Builder | ||
public class ItemBriefDtos { | ||
private List<ItemBriefDto> items; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.example.flab.soft.shoppingmallfashion.item.service; | ||
|
||
import com.example.flab.soft.shoppingmallfashion.item.domain.Sex; | ||
import com.example.flab.soft.shoppingmallfashion.item.repository.ItemRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.cache.annotation.CacheEvict; | ||
import org.springframework.cache.annotation.Cacheable; | ||
import org.springframework.data.domain.Pageable; | ||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class ItemCacheService { | ||
private final ItemRepository itemRepository; | ||
|
||
@Transactional(readOnly = true) | ||
@Cacheable(cacheNames = "ITEM_LIST", | ||
key = "#categoryId + ':' + #storeId + ':' + #pageable.pageNumber", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 캐시 키에 pageNumber가 왜 있나요?? |
||
condition = "#pageable.pageNumber <= 3", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이런 조건을 넣으신 이유가 있을까요? |
||
cacheManager = "cacheManager") | ||
public ItemsDto getItems(Integer minPrice, Integer maxPrice, | ||
Long categoryId, Long storeId, Sex sex, Pageable pageable) { | ||
return ItemsDto.builder() | ||
.items(itemRepository.findAllByFilters(minPrice, maxPrice, categoryId, storeId, sex, pageable) | ||
.stream() | ||
.map(ItemBriefDto::new) | ||
.toList()) | ||
.build(); | ||
} | ||
|
||
@CacheEvict(cacheNames = "ITEM_DETAILS", | ||
key = "#itemId", | ||
cacheManager = "cacheManager") | ||
@Transactional | ||
public void deleteItemDetails(Long itemId) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에 구현하실 메서들에는 주석으로 설명 넣어주시는게 좋습니다. |
||
} | ||
|
||
@CacheEvict(cacheNames = "STOCKS", | ||
key = "#itemOptionId", | ||
cacheManager = "cacheManager") | ||
@Transactional | ||
public void deleteItemOptionStocks(Long itemOptionId) { | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
파일 명이 qa-deploy 맞나요?? 개발서버 또는 운영서버에 배포하는거아닌가요?