Skip to content

Commit

Permalink
Merge pull request #2 from NAGAZA-Team/feat/search
Browse files Browse the repository at this point in the history
  • Loading branch information
HyungJu authored Feb 26, 2024
2 parents 6d131e9 + 69174ad commit 331acd2
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package kr.nagaza.nagazaserver.domain.model

import java.util.*

data class CafeRoom(
val roomId: String,
val cafeId: String,
val genre: String,
val title: String,
val description: String,
val genre: Set<Genre>,
val timeout: Int,
val recommendedUserCnt: Int,
val roomImgUrl: String?,
val description: String,
val createdAt: Date,
val updatedAt: Date,
)
6 changes: 6 additions & 0 deletions src/main/kotlin/kr/nagaza/nagazaserver/domain/model/Genre.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package kr.nagaza.nagazaserver.domain.model

data class Genre(
val genreId: String,
val name: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ interface CafeRoomRepository {

fun findByRoomId(roomId: String): CafeRoom?

fun getAllGenres(): List<String>
fun search(
queryString: String?,
genre: String?,
address1: String?,
address2: String?,
cafeId: String?,
): List<CafeRoom>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kr.nagaza.nagazaserver.domain.exception.CafeRoomNotFoundException
import kr.nagaza.nagazaserver.domain.model.CafeRoom
import kr.nagaza.nagazaserver.domain.repository.CafeRepository
import kr.nagaza.nagazaserver.domain.repository.CafeRoomRepository
import kr.nagaza.nagazaserver.presenter.restapi.dto.request.RoomSearchQuery
import org.springframework.stereotype.Service

@Service
Expand All @@ -25,7 +26,13 @@ class CafeRoomService(
return cafeRoomRepository.findByRoomId(roomId) ?: throw CafeRoomNotFoundException()
}

fun getAllGenres(): List<String> {
return cafeRoomRepository.getAllGenres()
fun search(cafeRoomSearchQuery: RoomSearchQuery): List<CafeRoom> {
return cafeRoomRepository.search(
queryString = cafeRoomSearchQuery.queryString,
genre = cafeRoomSearchQuery.genre,
address1 = cafeRoomSearchQuery.address1,
address2 = cafeRoomSearchQuery.address2,
cafeId = cafeRoomSearchQuery.cafeId,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,75 @@ package kr.nagaza.nagazaserver.infrastructure.jpa.entity

import jakarta.persistence.*
import kr.nagaza.nagazaserver.domain.model.CafeRoom
import org.hibernate.annotations.CreationTimestamp
import java.util.*

@Entity(name = "cafe_room")
class CafeRoomEntity(
@Id
@Column(name = "room_id")
val roomId: String,

@Column(name = "cafe_id")
val cafeId: String,

@Column(name = "genre")
val genre: String,

@Column(name = "title")
val title: String,
@Column(name = "description")
val description: String,
@ManyToMany
@JoinTable(
name = "cafe_room_genre",
joinColumns = [JoinColumn(name = "room_id")],
inverseJoinColumns = [JoinColumn(name = "genre_id")],
)
val genre: MutableSet<GenreEntity> = mutableSetOf(),
@Column(name = "timeout")
val timeout: Int,

@Column(name = "recommend_user")
val recommendUserCnt: Int,

@Column(name = "room_img_url")
val roomImgUrl: String?,

@Column(name = "description")
val description: String,

@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
name = "cafe_room_like",
joinColumns = [JoinColumn(name = "room_id")],
inverseJoinColumns = [JoinColumn(name = "user_id")]
inverseJoinColumns = [JoinColumn(name = "user_id")],
)
val likedUsers: MutableSet<UserEntity> = mutableSetOf(),

@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "room_id")
val reviews: MutableList<CafeRoomReviewEntity> = mutableListOf(),
@Column(name = "created_at")
@CreationTimestamp()
val createdAt: Date,
val updatedAt: Date,
) {
fun toModel() = CafeRoom(
roomId = roomId,
cafeId = cafeId,
genre = genre,
timeout = timeout,
recommendedUserCnt = recommendUserCnt,
roomImgUrl = roomImgUrl,
description = description,
)
fun toModel() =
CafeRoom(
roomId = roomId,
cafeId = cafeId,
genre = genre.map { it.toModel() }.toSet(),
timeout = timeout,
recommendedUserCnt = recommendUserCnt,
roomImgUrl = roomImgUrl,
description = description,
title = title,
createdAt = createdAt,
updatedAt = updatedAt,
)

companion object {
fun fromModel(model: CafeRoom) = CafeRoomEntity(
roomId = model.roomId,
cafeId = model.cafeId,
genre = model.genre,
timeout = model.timeout,
recommendUserCnt = model.recommendedUserCnt,
roomImgUrl = model.roomImgUrl,
description = model.description,
)
fun fromModel(model: CafeRoom) =
CafeRoomEntity(
roomId = model.roomId,
cafeId = model.cafeId,
genre = model.genre.map { GenreEntity.fromModel(it) }.toMutableSet(),
timeout = model.timeout,
recommendUserCnt = model.recommendedUserCnt,
roomImgUrl = model.roomImgUrl,
title = model.title,
description = model.description,
createdAt = model.createdAt,
updatedAt = model.updatedAt,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package kr.nagaza.nagazaserver.infrastructure.jpa.entity

import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Id
import kr.nagaza.nagazaserver.domain.model.Genre

@Entity(name = "genre")
class GenreEntity(
@Id
@Column(name = "genre_id")
val genreId: String,
@Column(name = "name")
val name: String,
) {
fun toModel(): Genre {
return Genre(
genreId = genreId,
name = name,
)
}

companion object {
fun fromModel(genre: Genre): GenreEntity {
return GenreEntity(
genreId = genre.genreId,
name = genre.name,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package kr.nagaza.nagazaserver.infrastructure.jpa.repository

import com.querydsl.jpa.impl.JPAQuery
import jakarta.persistence.EntityManager
import jakarta.persistence.PersistenceContext
import kr.nagaza.nagazaserver.domain.model.CafeRoom
import kr.nagaza.nagazaserver.domain.repository.CafeRoomRepository
import kr.nagaza.nagazaserver.infrastructure.jpa.entity.QCafeEntity
import kr.nagaza.nagazaserver.infrastructure.jpa.entity.QCafeRoomEntity
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Repository

@Repository
class CafeRoomRepositoryImpl(
private val jpaCafeRoomRepository: JpaCafeRoomRepository,
@PersistenceContext
private val entityManager: EntityManager,
) : CafeRoomRepository {
override fun getAllGenres(): List<String> {
return jpaCafeRoomRepository.findAllGenres()
}

override fun getAllRoomByCafeId(cafeId: String): List<CafeRoom> {
return jpaCafeRoomRepository.findAllByCafeId(cafeId)
.map {
Expand All @@ -23,4 +26,45 @@ class CafeRoomRepositoryImpl(
override fun findByRoomId(roomId: String): CafeRoom? {
return jpaCafeRoomRepository.findByIdOrNull(roomId)?.toModel()
}

override fun search(
queryString: String?,
genre: String?,
address1: String?,
address2: String?,
cafeId: String?,
): List<CafeRoom> {
val cafeRoomEntity = QCafeRoomEntity.cafeRoomEntity
val cafeEntity = QCafeEntity.cafeEntity
val query =
JPAQuery<CafeRoom>(entityManager)
.select(cafeRoomEntity)
.from(cafeRoomEntity)
.leftJoin(cafeEntity).on(cafeRoomEntity.cafeId.eq(cafeEntity.cafeId))
.leftJoin(cafeRoomEntity.genre)

if (queryString != null) {
query.where(cafeRoomEntity.title.contains(queryString))
}

if (genre != null) {
query.where(cafeRoomEntity.genre.any().genreId.eq(genre))
}

if (address1 != null) {
query.where(cafeEntity.addressOne.eq(address1))
}

if (address2 != null) {
query.where(cafeEntity.addressTwo.eq(address2))
}

if (cafeId != null) {
query.where(cafeRoomEntity.cafeId.eq(cafeId))
}

return query.fetch().map {
it.toModel()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ package kr.nagaza.nagazaserver.infrastructure.jpa.repository

import kr.nagaza.nagazaserver.infrastructure.jpa.entity.CafeRoomEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query

interface JpaCafeRoomRepository : JpaRepository<CafeRoomEntity, String> {
fun findAllByCafeId(cafeId: String): List<CafeRoomEntity>

@Query("SELECT DISTINCT cafe_room.genre FROM cafe_room")
fun findAllGenres(): List<String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,29 @@ package kr.nagaza.nagazaserver.presenter.restapi.api
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import kr.nagaza.nagazaserver.presenter.restapi.dto.response.CafeRoomResponse
import org.springframework.data.repository.query.Param
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@Tag(name = "카페 방 API", description = "카페 방 관련 API")
@RestController
@RequestMapping("/v1/cafes/{cafeId}/rooms")
@RequestMapping("/v1/rooms")
interface CafeRoomApi {
@Operation(summary = "카페 전체 방 목록", description = "카페 내의 전체 방 목록을 반환합니다.")
@GetMapping
fun getCafeRooms(
@PathVariable cafeId: String,
@GetMapping("/search")
fun searchRooms(
@Param("queryString") queryString: String?,
@Param("genre") genre: String?,
@Param("address1") address1: String?,
@Param("address2") address2: String?,
@Param("cafeId") cafeId: String?,
): List<CafeRoomResponse>

@Operation(summary = "특정 방 조회", description = "카페 내의 특정 방 정보를 조회합니다.")
@GetMapping("/{roomId}")
fun getCafeRoom(
@PathVariable cafeId: String,
@PathVariable roomId: String,
): CafeRoomResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@ package kr.nagaza.nagazaserver.presenter.restapi.controller

import kr.nagaza.nagazaserver.domain.service.CafeRoomService
import kr.nagaza.nagazaserver.presenter.restapi.api.CafeRoomApi
import kr.nagaza.nagazaserver.presenter.restapi.dto.request.RoomSearchQuery
import kr.nagaza.nagazaserver.presenter.restapi.dto.response.CafeRoomResponse
import org.springframework.stereotype.Controller

@Controller
class CafeRoomController(
private val cafeRoomService: CafeRoomService,
) : CafeRoomApi {
override fun getCafeRooms(cafeId: String): List<CafeRoomResponse> {
return cafeRoomService.getRoomsByCafeId(cafeId)
.map(CafeRoomResponse::fromModel)
}

override fun getCafeRoom(cafeId: String, roomId: String): CafeRoomResponse {
override fun getCafeRoom(roomId: String): CafeRoomResponse {
return cafeRoomService.getRoomByRoomId(roomId)
.let(CafeRoomResponse::fromModel)
}

override fun searchRooms(
queryString: String?,
genre: String?,
address1: String?,
address2: String?,
cafeId: String?,
): List<CafeRoomResponse> {
return cafeRoomService.search(
RoomSearchQuery(
queryString = queryString,
genre = genre,
address1 = address1,
address2 = address2,
cafeId = cafeId,
),
).map(CafeRoomResponse::fromModel)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kr.nagaza.nagazaserver.presenter.restapi.dto.request

class RoomSearchQuery(
val queryString: String?,
val address1: String?,
val address2: String?,
val genre: String?,
val cafeId: String?,
)
Loading

0 comments on commit 331acd2

Please sign in to comment.