Skip to content

나예경 seminar1 과제#60

Open
yknxh wants to merge 12 commits into
wafflestudio:master-week1from
yknxh:master
Open

나예경 seminar1 과제#60
yknxh wants to merge 12 commits into
wafflestudio:master-week1from
yknxh:master

Conversation

@yknxh
Copy link
Copy Markdown

@yknxh yknxh commented Oct 2, 2023

No description provided.

Copy link
Copy Markdown
Member

@davin111 davin111 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다~ 👍

Comment on lines +15 to +16
val playlistServiceImpl: PlaylistServiceImpl,
val playlistlikeServiceImpl: PlaylistLikeServiceImpl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ktlint 등을 참고하셔 indent 를 일관되게 하면 좋을 것 같습니다.

Comment on lines +11 to +16
@ManyToOne
@JoinColumn(name = "playlist_id")
val playlist: PlaylistEntity,
@ManyToOne
@JoinColumn(name = "user_id")
val user: UserEntity
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어떠한 경우의 연관관계에도 Lazy 를 지향하는 것이 좋습니다. ManyToOne 의 default 가 EAGER 라 하더라도 이것을 변경해두는 것이 좋아요. wafflestudio/seminar-2023#169 를 참고하시면 좋습니다.

이걸 Lazy 로 해두었다면, 불필요한 N+1 쿼리가 덜 날아가서 곳곳에서 JOIN FETCH 를 덜 써도 되었을 수도 있어요.


override fun get(id: Long): Playlist {
TODO()
val plEntityList = playlistsongRepository.getPlaylistSongEntity(id)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서비스 코드 취지상 PlaylistEntity 를 가져오는 것이 자연스러울 거 같은데, List<PlaylistSongEntity> 를 가져오고 있네요.

이런 식으로 적절한 JOIN FETCH 와 함께 PlaylistEntity 를 가져온 다음에 OneToMany 로 있는 playlist_songs에 접근해 활용하는 식이 읽기 자연스러운 코드 같습니다.

@RestController
class SongController {
class SongController(
val songServiceImpl: SongServiceImpl
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring DI 의 이점을 활용하려면, 구현체인 Impl 이 아닌 SongService 타입으로 주입 받는 것이 맞습니다. 그래야 나중에 cache 를 이용한 SongService 의 다른 구현체로 바꿔끼더라도, 코드를 많이 수정할 필요 없이 원하는 Bean 으로 착착 갈아끼기 좋으니까요.

interface SongRepository : JpaRepository<SongEntity, Long> {
@Query(value = "SELECT s FROM songs s "
+ "JOIN FETCH s.album JOIN FETCH s.song_artists sa JOIN FETCH sa.song_artist "
+ "WHERE s.title LIKE %:keyword% ORDER BY length(s.title)")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쿼리로 DB 에서 length() 로 order 하는 것보단, 일단 application (서버) 에 가져와서 코드로 sort 하는 게 성능상 더 나은 선택일 것 같습니다.

+ "WHERE s.title LIKE %:keyword% ORDER BY length(s.title)")
fun findSongEntity(keyword: String): List<SongEntity>

} No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git 에서 파일의 마지막 newline 을 넣는 것이 좋은 습관입니다.

val playlistlike = playlistlikeRepository.getPlaylistLikeEntity(playlistId, userId)
if (!playlistlike.isPresent) throw PlaylistNeverLikedException()

playlistlikeRepository.delete(playlistlike.get())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

참고로, deleteByXxx...() 같은 식으로 repository 메서드를 만들어서 삭제 쿼리를 날릴 수도 있습니다.

Comment on lines +8 to +10
@Query("SELECT pl FROM playlist_likes pl "
+ "WHERE pl.playlist.id = :playlistId and pl.user.id = :userId")
fun getPlaylistLikeEntity(playlistId: Long, userId: Long): Optional<PlaylistLikeEntity>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 정도 쿼리는 직접 @Query로 JPQL 을 적지 않고, findByPlaylistIdAndUserId()으로 메서드 이름을 지어주면 spring data 가 동일 쿼리를 만들어줍니다.

그리고, Kotlin 에서는 Optional 을 굳이 쓸 필요 없이 PlaylistLikeEntity?를 쓰면 됩니다. 이에 대해서는 wafflestudio/seminar-2023#160 (reply in thread) 를 참고해보세요.

package com.wafflestudio.seminar.spring2023.playlist.repository

import org.springframework.data.jpa.repository.JpaRepository
import java.util.*
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

불필요한 import 지우기

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants