이상하게 dto는 DTO로해야 인식을 잘하는것 같다. Dto가 아니라 DTO다.
새 브런치 만들고 풀 리퀘스트 하는법
git checkout -b 새브랜치 이름
git add . git commit -m"메시지" git push origin 새브랜치이름 하고 깃허브에 가서 생성된 브랜치를 누르고 풀 리퀘스트를 누르고 main이 아니라 dev로 바꾸면 된다. 그리고 그뒤론 평범하게 add .이랑 commit를 하면 된다. 그리고 다른사람의 브랜치를 받아올때엔 git pull origin 브랜치이름 하면 된다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
아이디는 이렇게 해야한다. id를 데이터베이스에 맡기겠다는 뜻이다.
override fun updateSong(albumId: Long, songId: Long, songModifyDTO: SongUpdateDTO): SongDTO {
val song = songRepository.findById(songId).orElseThrow { NoSuchElementException("곡을 찾을 수 없습니다.") }
song.title = songModifyDTO.title
song.composer = songModifyDTO.composer
song.lyrics = songModifyDTO.lyrics
song.link = songModifyDTO.link
songRepository.save(song)
}
여기에서 에러가 나서 alt enter가 말하는대로 TODO를 추가했었는데, 그게 아니라 이건 Song를 entity에서 dto로 전환하면 된다고 한다.
오늘 세션에서 배운것!
mvc는?
모델 뷰 컨트롤러
모델이 데이터를 관리하는 부분 뷰는? 뷰는 html이다. 즉, 보여지는 화면이다.
뷰를 안쓰면 컨트롤러 디스패쳐, 클라이언트로. @Responsebody를 쓰면 뷰를 안쓴다는 뜻. 우리는 restcontroller을 쓰는데, 거기에 포함되어있다. 그래서 우리는 MVC기반이지만, MVC패턴은 아니다.
컨트롤러는 클라이언트의 요청을 직접 가공해서 전달해주고 정보가 서비스에서 요구하는것과 같은지 검증. 즉, 쓸모없는 정보인지 검증한다.
서비스는 비즈니스 로직이며 데이터베이스에 접근해야할때 layer(Repository)호출, 요청정보가 유효한지 체크. 이게 가장 중요. 널인지 아닌지 이것도 여기서 체크한다.
리포지터리는 쿼리가 생성되는 계층. 이녀석이 서비스랑 연결된다.
비즈니스 코드는 전부 서비스에만 넣어야 하는가?
서비스에선 호출만 하고 다른곳에 위임해도 된다.
그리고 서비스는 만능이 되선 안되고 간결하게.
dto, entity 전환은 companion써서 그 안에서 해결이 가능하다고 한다.
그래서 , song class를 dto로 변환하려고 한 결과,
package com.example.codingsonyeondan.domain.songs
import com.example.codingsonyeondan.domain.album.model.Album
import com.example.codingsonyeondan.domain.songs.dto.SongDTO
import jakarta.persistence.*
@Entity
@Table(name = "song", schema = "public")
data class Song(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val id: Long = 0,
@Column(name = "title")
var title: String,
@Column(name = "composer")
var composer: String,
@Column(name = "lyrics")
var lyrics: String,
@Column(name = "link")
var link: String,
@ManyToOne
@JoinColumn(name = "album_id", nullable = false)
var album: Album? = null
){
companion object {
fun toDto(song: Song): SongDTO {
return SongDTO(
id = song.id,
title = song.title,
composer = song.composer,
lyrics = song.lyrics,
link = song.link,
)
}
}
}
이렇게 compain object를 써서 dto로 변환시키고,
override fun updateSong(albumId: Long, songId: Long, songModifyDTO: SongUpdateDTO): SongDTO {
val song = songRepository.findById(songId).orElseThrow { NoSuchElementException("곡을 찾을 수 없습니다.") }
song.title = songModifyDTO.title
song.composer = songModifyDTO.composer
song.lyrics = songModifyDTO.lyrics
song.link = songModifyDTO.link
songRepository.save(song)
return Song.toDto(song)
}
이걸로 위에서 오류가 났던걸 dto로 받아주면서 수정이 된다. 그런데, serviceimpl에 빨간줄이 그어지는게 아닌가?
인텔리제이는 이걸 abstract로 추상화 하라고 했지만, 아무래도 그건 아닌거 같아서 에러코드로 뜬 Class 'SongServiceImpl' is not abstract and does not implement abstract member public abstract fun getSongs(albumId: Long): List<SongDTO> defined in cohttp://m.example.codingsonyeondan.domain.songs.service.SongService
이것을 검색해본 결과, 내가 원래 존재했었던 getsong이랑 getsongs가 있었는데, 중복된줄 알고 하나를 지워버려서 그런거였다.
그래서 다시 그걸 복구한뒤 실행을 하자 org.postgresql.util.PSQLException: This connection has been closed.
이런 메시지가 뜨면서 안되는것이 아닌가? 도대체 왜? 이러면서 찾아본 결과,
인터넷이 끊겨서 그런거였다. 왠지 오늘은 인터넷이 수시로 끊겼는데, 그래서 인터넷 끊긴걸 모르고 실행을 시켜서 그런거였다. 인터넷이 다시 연결되자 문제없이 작동하는것이 보였다. 다행이였다.