Skip to content

Commit

Permalink
Merge branch 'main' into feat/BSVR-25
Browse files Browse the repository at this point in the history
  • Loading branch information
pminsung12 authored Jul 5, 2024
2 parents 45138a9 + eca8047 commit 15d7817
Show file tree
Hide file tree
Showing 18 changed files with 314 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_size = 4
indent_style = space
insert_final_newline = false
max_line_length = 100
Expand Down
19 changes: 19 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
name: 버그 레포트
about: 버그 제보 & QA
title: "[BUG] "
labels: 🐛 Bug
assignees: ""
---

## 📍 재현 위치

<!-- 이슈가 발생한 API나 어플 스크린샷, 실행 환경(OS) 등을 알려주세요. -->

## 📌 상황 설명

<!-- 발생한 버그에 대해 알려주세요. (e.g. A 버튼 클릭시 B 오류가 발생했어요.) -->

## 🤔 정상 기대값 (선택)

<!-- 정상적으로 동작했다면 어떤 결과가 나와야 하는지 알려주세요. -->
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/suggest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: Suggest
about: 프로젝트 관련해서 무엇이든 제안해주세요!
title: "[제안]"
labels: 👋 Suggest
assignees: ""
---

## 💁‍♀️ 제안 사항

<!-- 제안할 내용을 적어주세요. -->


## 👀 제안 이유

<!-- 제안하는 이유를 알려주세요. (e.g., 이 제안을 통해 우리가 얻을 수 있는 것 등) -->


## ✅ 참고 사항

<!-- 공유할 내용, 스크린샷 등을 넣어 주세요. -->
8 changes: 7 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@

## 🌱 연관 내용 (선택)

- 관련 있는 내용, 또는 앞으로 고려할 내용을 적어주세요.
- 관련 있는 내용, 또는 앞으로 고려할 내용을 적어주세요.

<br>

## 💻 실행 화면 (필수)

- 실행 결과 사진을 첨부해주세요.
71 changes: 71 additions & 0 deletions .github/workflows/dev-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build And Test

on:
push:
branches:
- dev
- main
pull_request:
branches:
- dev
- main

jobs:
build-and-test:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "corretto"

- name: Cache Gradle
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: ./gradlew build -x test --stacktrace --parallel

- name: Run tests
run: ./gradlew test

- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: '**/build/test-results/test/TEST-*.xml'

- name: JUnit Report Action
uses: mikepenz/action-junit-report@v3
if: always()
with:
report_paths: '**/build/test-results/test/TEST-*.xml'

- name: Store test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: '**/build/test-results/test/TEST-*.xml'

- name: Test Report Summary
if: always()
run: |
echo '## Test Report Summary' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
./gradlew test --console=plain || true
echo '```' >> $GITHUB_STEP_SUMMARY
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package org.depromeet.spot.application.member.controller;

import java.util.List;

import org.depromeet.spot.application.member.dto.request.MemberRequest;
import org.depromeet.spot.application.member.dto.response.MemberResponse;
import org.depromeet.spot.usecase.port.in.MemberUsecase;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.val;
Expand All @@ -31,4 +36,14 @@ public MemberResponse create(@RequestBody MemberRequest request) {
val member = memberUsecase.create(request.name());
return MemberResponse.from(member);
}

@GetMapping
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "이름으로 Member 조회하는 API")
public List<MemberResponse> findByName(
@RequestParam("name") @Parameter(name = "name", description = "사용자 이름", required = true)
final String name) {
val memberList = memberUsecase.findByName(name);
return memberList.stream().map(MemberResponse::from).toList();
}
}
10 changes: 10 additions & 0 deletions infrastructure/jpa/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ dependencies {
// spring
implementation("org.springframework.boot:spring-boot-starter-data-jpa:_")


runtimeOnly("com.mysql:mysql-connector-j")

// queryDSL
implementation("com.querydsl:querydsl-jpa:_:jakarta")
annotationProcessor("com.querydsl:querydsl-apt:_:jakarta")
annotationProcessor("jakarta.annotation:jakarta.annotation-api")
annotationProcessor("jakarta.persistence:jakarta.persistence-api")

// p6spy
implementation("com.github.gavlyukovskiy:p6spy-spring-boot-starter:_")
}

tasks.bootJar { enabled = false }
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package org.depromeet.spot.jpa.common;

import java.util.Locale;

import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.springframework.context.annotation.Configuration;

import com.p6spy.engine.logging.Category;
import com.p6spy.engine.spy.appender.MessageFormattingStrategy;

@Configuration
public class P6spySqlFormatter implements MessageFormattingStrategy {

private static String ROOT_PACKAGE = "org.depromeet.spot";
private static String P6SPY_PACKAGE = "org.depromeet.spot.jpa.common.P6spySqlFormatter";

@Override
public String formatMessage(
int connectionId,
String now,
long elapsed,
String category,
String prepared,
String sql,
String url) {
sql = formatSql(category, sql);
return String.format(
"[%s] | took %d ms | connectionId %d | %s | %s",
category, elapsed, connectionId, filterStack(), formatSql(category, sql));
}

private String formatSql(String category, String sql) {
if (isNotEmpty(sql) && isStatement(category)) {
String trimmedSQL = sql.trim().toLowerCase(Locale.ROOT);
if (isDDL(trimmedSQL)) {
return FormatStyle.DDL.getFormatter().format(sql);
}
return FormatStyle.BASIC.getFormatter().format(sql);
}
return sql;
}

// 일반적인 쿼리인지 판단
// 트랜잭션 커밋, 롤백 등 쿼리가 아닌 작업은 포맷팅하지 않는다.
private boolean isStatement(String category) {
return Category.STATEMENT.getName().equals(category);
}

private boolean isNotEmpty(String sql) {
return sql != null && !sql.trim().isEmpty();
}

private boolean isDDL(String sql) {
return (sql.startsWith("create")) || sql.startsWith("alter") || sql.startsWith("comment");
}

private String filterStack() {
StackTraceElement[] stackTraces = new Throwable().getStackTrace();
StringBuilder sb = new StringBuilder();
int order = 1;

for (StackTraceElement element : stackTraces) {
String trace = element.toString();
if (trace.startsWith(ROOT_PACKAGE) && !trace.contains(P6SPY_PACKAGE)) {
sb.append("\n\t\t").append(order++).append(".").append(trace);
}
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.depromeet.spot.jpa.config;

import jakarta.annotation.PostConstruct;

import org.depromeet.spot.jpa.common.P6spySqlFormatter;
import org.springframework.context.annotation.Configuration;

import com.p6spy.engine.spy.P6SpyOptions;

@Configuration
public class P6spyConfig {

@PostConstruct
public void setLogMessageFormat() {
P6SpyOptions.getActiveInstance().setLogMessageFormat(P6spySqlFormatter.class.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.depromeet.spot.jpa.config;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.querydsl.jpa.impl.JPAQueryFactory;

@Configuration
public class QueryDslConfig {

@PersistenceContext private EntityManager entityManager;

@Bean
public JPAQueryFactory queryFactory() {
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.depromeet.spot.jpa.member.repository;

import static org.depromeet.spot.jpa.member.entity.QMemberEntity.memberEntity;

import java.util.List;

import org.depromeet.spot.jpa.member.entity.MemberEntity;
import org.springframework.stereotype.Repository;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class MemberCustomRepository {

private final JPAQueryFactory queryFactory;

public List<MemberEntity> findByName(final String name) {
return queryFactory.selectFrom(memberEntity).where(eqMemberName(name)).fetch();
}

private BooleanExpression eqMemberName(final String name) {
if (name == null) {
return null;
}
return memberEntity.name.eq(name);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.depromeet.spot.jpa.member.repository;

import java.util.List;

import org.depromeet.spot.domain.member.Member;
import org.depromeet.spot.jpa.member.entity.MemberEntity;
import org.depromeet.spot.usecase.port.out.MemberRepository;
Expand All @@ -13,10 +15,17 @@
public class MemberRepositoryImpl implements MemberRepository {

private final MemberJpaRepository memberJpaRepository;
private final MemberCustomRepository memberCustomRepository;

@Override
public Member save(Member member) {
val memberEntity = memberJpaRepository.save(MemberEntity.from(member));
return memberEntity.toDomain();
}

@Override
public List<Member> findByName(String name) {
val memberEntities = memberCustomRepository.findByName(name);
return memberEntities.stream().map(MemberEntity::toDomain).toList();
}
}
3 changes: 2 additions & 1 deletion infrastructure/jpa/src/main/resources/application-jpa.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ logging:
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE

# 필요한 경우 추가 설정
# 필요한 경우 추가 설정

Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.depromeet.spot.usecase.port.in;

import java.util.List;

import org.depromeet.spot.domain.member.Member;

public interface MemberUsecase {

Member create(String name);

List<Member> findByName(String name);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package org.depromeet.spot.usecase.port.out;

import java.util.List;

import org.depromeet.spot.domain.member.Member;

public interface MemberRepository {

Member save(Member member);

List<Member> findByName(String name);
}
Loading

0 comments on commit 15d7817

Please sign in to comment.