Skip to content

Commit

Permalink
Merge pull request #124 from MYONGSIK/develop
Browse files Browse the repository at this point in the history
main <- dev
  • Loading branch information
Qbeom0925 authored Jun 6, 2023
2 parents ea31d8a + 22854c1 commit 66ea19e
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 12 deletions.
10 changes: 10 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<img width="100%" height="45%" src="https://user-images.githubusercontent.com/61505572/220684641-9b041a02-447d-47e5-812b-76d457da5689.png">

<h3>Infra Structure</h3>
<img width="100%" height="45%" src="https://user-images.githubusercontent.com/61505572/220687135-a6f83cba-35cd-4895-a72e-ef29f5f4a3a7.png">
<img width="100%" height="45%" src="https://user-images.githubusercontent.com/53048655/234185319-d80b3ba2-a144-4df2-91e1-4f68eefdd026.png">


<br><br>
Expand Down
26 changes: 26 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.7.4'
implementation 'org.springframework.boot:spring-boot-starter-logging'

// mongo
// implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
Expand All @@ -49,8 +50,33 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-core'
implementation 'io.micrometer:micrometer-registry-prometheus'

//QueryDSL
implementation "com.querydsl:querydsl-jpa"
implementation "com.querydsl:querydsl-core"
implementation "com.querydsl:querydsl-collections"
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jpa" // querydsl JPAAnnotationProcessor ์‚ฌ์šฉ ์ง€์ •
annotationProcessor "jakarta.annotation:jakarta.annotation-api" // java.lang.NoClassDefFoundError (javax.annotation.Generated) ๋Œ€์‘ ์ฝ”๋“œ
annotationProcessor "jakarta.persistence:jakarta.persistence-api" // java.lang.NoClassDefFoundError (javax.annotation.Entity) ๋Œ€์‘ ์ฝ”๋“œ
}

tasks.named('test') {
useJUnitPlatform()
}
// Querydsl ์„ค์ •๋ถ€
def generated = 'build/generated'

// querydsl QClass ํŒŒ์ผ ์ƒ์„ฑ ์œ„์น˜๋ฅผ ์ง€์ •
tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
}

// java source set ์— querydsl QClass ์œ„์น˜ ์ถ”๊ฐ€
sourceSets {
main.java.srcDirs += [ generated ]
}

// gradle clean ์‹œ์— QClass ๋””๋ ‰ํ† ๋ฆฌ ์‚ญ์ œ
clean {
delete file(generated)
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package com.example.myongsick.domain.scrap.dto;

import com.querydsl.core.annotations.QueryProjection;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "์ฐœ๊ฝ ๋ฆฌ์ŠคํŠธ ์‘๋‹ต ๊ฐ์ฒด ( + ์ฐœ๊ฝ์ˆ˜ ํฌํ•จ )")
public class ScrapCountResponse {

Expand All @@ -20,12 +17,28 @@ public class ScrapCountResponse {
private String name;
private String category;
private String address;
private String contact;
private String urlAddress;
private String distance;
private String contact;
private String latitude;
private String longitude;
private int scrapCount;
@QueryProjection
public ScrapCountResponse(Long storeId, String code, String name, String category, String address,
String contact, String urlAddress, String distance, String latitude, String longitude,
int scrapCount) {
this.storeId = storeId;
this.code = code;
this.name = name;
this.category = category;
this.address = address;
this.contact = contact;
this.urlAddress = urlAddress;
this.distance = distance;
this.latitude = latitude;
this.longitude = longitude;
this.scrapCount = scrapCount;
}

public static ScrapCountResponse toDto(CountResponse countResponse) {
return ScrapCountResponse.builder()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.myongsick.domain.scrap.repository;

import com.example.myongsick.domain.scrap.dto.ScrapCountResponse;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;

public interface ScrapRepositoryCustom {
Page<ScrapCountResponse> findAllByCampusWithPaging(@Param("campus") String campus, Pageable pageable);

Optional<ScrapCountResponse> findByIdCustom(Long storeId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.example.myongsick.domain.scrap.repository;

import static com.example.myongsick.domain.scrap.entity.QScrap.scrap;
import static com.example.myongsick.domain.scrap.entity.QStore.store;

import com.example.myongsick.domain.scrap.dto.QScrapCountResponse;
import com.example.myongsick.domain.scrap.dto.ScrapCountResponse;
import com.example.myongsick.domain.scrap.entity.CampusType;
import com.example.myongsick.domain.scrap.entity.Store;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;

@Repository
@RequiredArgsConstructor
public class ScrapRepositoryImpl implements ScrapRepositoryCustom{
private final JPAQueryFactory jpaQueryFactory;

@Override
public Page<ScrapCountResponse> findAllByCampusWithPaging(String campus, Pageable pageable) {
List<ScrapCountResponse> result = jpaQueryFactory.select(new QScrapCountResponse(store.id.as("storeId"), store.code, store.name, store.category, store.address, store.contact, store.urlAddress, store.distance, store.latitude, store.longitude, store.scrapList.size().as("scrapCount")))
.from(store)
.where(store.campus.eq(CampusType.valueOf(campus)))
.groupBy(store.code)
.orderBy(getOrderSpecifier(pageable.getSort()).stream().toArray(OrderSpecifier[]::new))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();

Long count = jpaQueryFactory
.select(scrap.count())
.from(scrap)
.fetchOne();

return new PageImpl<>(result, pageable, count);
}

@Override
public Optional<ScrapCountResponse> findByIdCustom(Long storeId) {
return Optional.ofNullable(jpaQueryFactory.select(new QScrapCountResponse(store.id.as("storeId"), store.code, store.name, store.category, store.address, store.contact, store.urlAddress, store.distance, store.latitude, store.longitude, store.scrapList.size().as("scrapCount")))
.from(store)
.where(store.id.eq(storeId))
.fetchOne());
}

private List<OrderSpecifier> getOrderSpecifier(Sort sort) {
List<OrderSpecifier> orderSpecifiers = new ArrayList<>();
sort.stream()
.forEach(order -> {
Order direction = order.isAscending() ? Order.ASC : Order.DESC;
String property = order.getProperty();
if(property.equals("scrapCount")) {
orderSpecifiers.add(new OrderSpecifier(direction, store.scrapList.size()));
} else if(property.equals("distance")) {
orderSpecifiers.add(new OrderSpecifier(direction, store.distance.castToNum(Long.class)));
} else {
PathBuilder orderByExpression = new PathBuilder(Store.class, "store");
orderSpecifiers.add(new OrderSpecifier(direction, orderByExpression.get(property)));
}
});
return orderSpecifiers;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.example.myongsick.domain.scrap.dto.ScrapCountResponse;
import com.example.myongsick.domain.scrap.dto.ScrapRequest;
import com.example.myongsick.domain.scrap.dto.ScrapResponse;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.example.myongsick.domain.scrap.exception.NotFoundScrapException;
import com.example.myongsick.domain.scrap.exception.NotFoundStoreException;
import com.example.myongsick.domain.scrap.repository.ScrapRepository;
import com.example.myongsick.domain.scrap.repository.ScrapRepositoryCustom;
import com.example.myongsick.domain.scrap.repository.StoreRepository;
import com.example.myongsick.domain.user.entity.User;
import com.example.myongsick.domain.user.exception.NotFoundUserException;
Expand Down Expand Up @@ -39,6 +40,7 @@ public class ScrapServiceImpl implements ScrapService{
private final UserRepository userRepository;
private final ScrapRepository scrapRepository;
private final StoreRepository storeRepository;
private final ScrapRepositoryCustom scrapRepositoryCustom;

@Value("${kakao.rest-key}")
private String kakaoRestKey;
Expand Down Expand Up @@ -80,7 +82,8 @@ public void deleteScrap(Long scrapId) {

@Override
public Page<ScrapCountResponse> getScrapCount(String campus, Pageable pageable) {
return scrapRepository.findAllCustom(campus, pageable).map(ScrapCountResponse::toDto);
// return scrapRepositoryCustom.findAllCustom(campus, pageable).map(ScrapCountResponse::toDto);
return scrapRepositoryCustom.findAllByCampusWithPaging(campus, pageable);
}

@Transactional
Expand Down Expand Up @@ -113,6 +116,7 @@ public void updateStore() {

@Override
public ScrapCountResponse getStoreOne(Long storeId) {
return storeRepository.findByIdCustom(storeId).map(ScrapCountResponse::toDto).orElseThrow(NotFoundStoreException::new);
// return storeRepository.findByIdCustom(storeId).map(ScrapCountResponse::toDto).orElseThrow(NotFoundStoreException::new);
return scrapRepositoryCustom.findByIdCustom(storeId).orElseThrow(NotFoundStoreException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.myongsick.global.config;

import com.querydsl.jpa.impl.JPAQueryFactory;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QueryDslConfig {

@PersistenceContext
private EntityManager em;

@Bean
public JPAQueryFactory jpaQueryFactory(EntityManager em) {
return new JPAQueryFactory(em);
}
}
8 changes: 7 additions & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ spring:
url: ENC(jV5Al684UF9ZuGwX0AJ4KaAl2djrcg5+mZe+QMgY1i2Afu6rtj0Cmrj52fkzjiQAP3b31dyhrLvggD+Mold//xi+7WPdEEu7AjoO1XGbMNl5uf5hKMhUh5pmZDpCkubJgj/VFoVUe4s=)
username: ENC(W14O0+528BmR05t/tOqkJA==)
password: ENC(8K7aplBAKgyNF7OuP11M6cXlCT1zLzm4)
driver-class-name: com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
log:
config:
path: ./logs
filename: app-dev
maxHistory: 7 # 7์ผ
totalSizeCap: 10MB # ๋กœ๊ทธ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ
8 changes: 7 additions & 1 deletion src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ spring:
url: ENC(rMxUsofvraIkaMgSRzwu8g6UfnSv1t+I57CAt4Id+qR0Woi/yGJ/dAyT6+KqF/McGN7uSI8aYef1DuWJu13N+1iHbFTfQZbDNalt8A3Lm4MwU0MxUA7o0qf+DU0043KdS8wag3pNGwA=)
username: ENC(AtyIP2KxL11MVrdq2yBI9Q==)
password: ENC(dc0+G3VP0z9eZQ+vZZg49KFbrCubCsQj)
driver-class-name: com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
log:
config:
path: /var/log/app
filename: app-dev
maxHistory: 3 # 3์ผ
totalSizeCap: 50MB # ๋กœ๊ทธ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ spring:
---
spring:
profiles:
active: local
active: local
59 changes: 59 additions & 0 deletions src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- ๋กœ๊ทธ ํŒจํ„ด์— ์ƒ‰์ƒ ์ ์šฉ %clr(pattern){color}
https://logback.qos.ch/manual/layouts.html#coloring
-->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />

<springProfile name="dev">
<property resource="application-dev.yml" />
</springProfile>

<!-- log ๋ณ€์ˆ˜ ๊ฐ’ ์„ค์ • -->
<springProperty name="LOG_PATH" source= "log.config.path" />
<springProperty name="LOG_FILE_NAME" source= "log.config.filename" />
<springProperty name="LOG_MAX_HISTORY" source= "log.config.maxHistory" />
<springProperty name="LOG_TOTAL_SIZE_CAP" source= "log.config.totalSizeCap" />

<property name="CONSOLE_LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss}:%-3relative] %clr(%-5level) %clr(${PID:-}){magenta} %clr(---){faint} %clr([%15.15thread]){faint} %clr(%-40.40logger{36}){cyan} %clr(:){faint} %msg%n"/>
<property name="FILE_LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss}:%-3relative] %-5level ${PID:-} --- [%15.15thread] %-40.40logger{36} : %msg%n"/>

<!-- ์ฝ˜์†”(STDOUT) -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
</layout>
</appender>

<!-- ํŒŒ์ผ(FILE) -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- log ๊ธฐ๋กํ•  ํŒŒ์ผ ์œ„์น˜ ์„ค์ • -->
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<!-- log ๊ธฐ๋ก ํƒ€์ž… ์ธ์ฝ”๋”ฉ -->
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>${LOG_MAX_HISTORY}</maxHistory>
<totalSizeCap>${LOG_TOTAL_SIZE_CAP}</totalSizeCap>
</rollingPolicy>
</appender>

<!-- spring profile๋ณ„ ๋กœ๊ทธ ์„ค์ • -->
<!-- dev ํ™˜๊ฒฝ -->
<springProfile name="dev">
<root level="info">
<!-- ์ฐธ์กฐํ•  appender - STDOUT -->
<appender-ref ref="STDOUT" />
</root>
<logger name="org.springframework.web" level="debug">
<!-- ์ฐธ์กฐํ•  appender - FILE -->
<appender-ref ref="FILE" />
</logger>
</springProfile>

</configuration>

0 comments on commit 66ea19e

Please sign in to comment.