diff --git a/.editorconfig b/.editorconfig index e41a4de5..4eab9d38 100644 --- a/.editorconfig +++ b/.editorconfig @@ -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 diff --git a/application/src/main/java/org/depromeet/spot/application/member/controller/MemberController.java b/application/src/main/java/org/depromeet/spot/application/member/controller/MemberController.java index f7b9c633..673abfb3 100644 --- a/application/src/main/java/org/depromeet/spot/application/member/controller/MemberController.java +++ b/application/src/main/java/org/depromeet/spot/application/member/controller/MemberController.java @@ -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; @@ -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 findByName( + @RequestParam("name") @Parameter(name = "name", description = "사용자 이름", required = true) + final String name) { + val memberList = memberUsecase.findByName(name); + return memberList.stream().map(MemberResponse::from).toList(); + } } diff --git a/infrastructure/jpa/build.gradle.kts b/infrastructure/jpa/build.gradle.kts index 72d73e5c..5a06ab8d 100644 --- a/infrastructure/jpa/build.gradle.kts +++ b/infrastructure/jpa/build.gradle.kts @@ -5,12 +5,17 @@ dependencies { // spring implementation("org.springframework.boot:spring-boot-starter-data-jpa:_") + // 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:_") // h2 - DB (또는 도커) 세팅 후 사라질 예정,, runtimeOnly("com.h2database:h2") - } tasks.bootJar { enabled = false } diff --git a/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/config/QueryDslConfig.java b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/config/QueryDslConfig.java new file mode 100644 index 00000000..5b64ca95 --- /dev/null +++ b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/config/QueryDslConfig.java @@ -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); + } +} diff --git a/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberCustomRepository.java b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberCustomRepository.java new file mode 100644 index 00000000..f0d490a7 --- /dev/null +++ b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberCustomRepository.java @@ -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 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); + } +} diff --git a/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberRepositoryImpl.java b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberRepositoryImpl.java index 42507851..8c4ebba9 100644 --- a/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberRepositoryImpl.java +++ b/infrastructure/jpa/src/main/java/org/depromeet/spot/jpa/member/repository/MemberRepositoryImpl.java @@ -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; @@ -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 findByName(String name) { + val memberEntities = memberCustomRepository.findByName(name); + return memberEntities.stream().map(MemberEntity::toDomain).toList(); + } } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/port/in/MemberUsecase.java b/usecase/src/main/java/org/depromeet/spot/usecase/port/in/MemberUsecase.java index 79af200b..42b00e6e 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/port/in/MemberUsecase.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/port/in/MemberUsecase.java @@ -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 findByName(String name); } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/port/out/MemberRepository.java b/usecase/src/main/java/org/depromeet/spot/usecase/port/out/MemberRepository.java index b7b5fe40..58da7024 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/port/out/MemberRepository.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/port/out/MemberRepository.java @@ -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 findByName(String name); } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/MemberService.java b/usecase/src/main/java/org/depromeet/spot/usecase/service/MemberService.java index 061ec57c..3e04c948 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/MemberService.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/service/MemberService.java @@ -1,5 +1,7 @@ package org.depromeet.spot.usecase.service; +import java.util.List; + import org.depromeet.spot.domain.member.Member; import org.depromeet.spot.usecase.port.in.MemberUsecase; import org.depromeet.spot.usecase.port.out.MemberRepository; @@ -19,4 +21,9 @@ public Member create(final String name) { val member = new Member(null, name); return memberRepository.save(member); } + + @Override + public List findByName(final String name) { + return memberRepository.findByName(name); + } } diff --git a/versions.properties b/versions.properties index c3ce1b2e..5844e6f2 100644 --- a/versions.properties +++ b/versions.properties @@ -25,3 +25,7 @@ version.org.springdoc..springdoc-openapi-starter-webmvc-ui=2.5.0 version.com.github.gavlyukovskiy..p6spy-spring-boot-starter=1.9.0 +version.com.querydsl..querydsl-apt=5.0.0 + +version.com.querydsl..querydsl-jpa=5.0.0 +