roomDB 는 안드로이드가 지원하는 데이터베이스이다. 이전까지는 방대한 데이터를 저장할 일이 없어서, (키+값) 의 쌍으로 저장하는 SharedPreference 를 주로 사용하곤 했다.
그러나, 방대한 데이터를 저장하고, 삽입,삭제,수정 등과 같은 메소드를 사용하기 위해선 roomDB 를 사용해야 한다.
1) Entity
package com.example.flo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "SongTable")
data class Song(
var title : String = "",
var singer : String = "",
var second : Int = 0,
var playTime : Int = 0, // 총 재생시간
var isPlaying : Boolean = false,
var music : String = "",
var coverImg: Int? = null,
var isLike: Boolean = false,
var albumIdx: Int = 0 // 이 song이 어떤 앨범에 담겨 있는지 가리키는 변수 (foreign key 역할)
){
@PrimaryKey(autoGenerate = true) var id: Int = 0
}
Entity 는 데이터베이스의 테이블과 같다고 생각하면 될 것이다.
data class에 @Entity 를 붙여주고, 테이블 이름을 지정한 후, 저장하고 싶은 속성의 변수 이름과 타입을 정해준다.
primaryKey는 키 값이기 때문에 유일한 값이어야 한다.
직접 지정해도 되지만 autoGenerate를 true로 주면 자동으로 값을 생성한다.
2) DAO
Data Access Object의 줄임말로, 데이터에 접근할 수 있는 메서드(삽입, 삭제, 수정 등등 ) 를 정의해놓은 인터페이스이다.
package com.example.flo
import androidx.room.*
@Dao
interface SongDao {
@Insert
fun insert(song: Song)
@Update
fun update(song: Song)
@Delete
fun delete(song: Song)
@Query("SELECT * FROM SongTable") // 테이블의 모든 값을 가져와라
fun getSongs(): List<Song>
@Query("SELECT * FROM SongTable WHERE id = :id")
fun getSong(id: Int): Song
@Query("SELECT * FROM SongTable WHERE albumIdx = :albumIdx")
fun getSongsInAlbum(albumIdx: Int): List<Song>
@Query("DELETE FROM LikeSongTable WHERE userId = :userID")
fun updateDisLikeAll(userID: Int)
@Insert
fun likeSong(likedSongs: LikedSongs)
@Query("SELECT id FROM LikeSongTable WHERE userId = :userID AND songId = :songID")
fun isLikeSong(userID: Int, songID: Int): Int?
@Query("DELETE FROM LikeSongTable WHERE userId = :userID AND songId = :songID")
fun disLikeAlbum(userID: Int, songID: Int): Int?
@Query("SELECT ST.* FROM LikeSongTable as LT LEFT JOIN SongTable as ST ON songId = ST.id WHERE LT.userId = :userId")
fun getLikedSongs(userId: Int): List<Song>
}
데이터베이스를 사용할 때마다 그때그때 필요한 메서드가 생겨서, 좀 많아진 상태이다.
SQL 문법으로 query 문을 작성하고, 원하는 값들을 가져올 수 있도록 복잡한 메서드들을 작성할 수 있다.
3) roomDB
package com.example.flo
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Song::class, Album::class, User::class, Like::class, LikedSongs::class], version = 4)
abstract class SongDatabase: RoomDatabase() {
abstract fun albumDao(): AlbumDao
abstract fun songDao(): SongDao
abstract fun userDao(): UserDao
companion object {
private var instance: SongDatabase? = null
@Synchronized
fun getInstance(context: Context): SongDatabase? {
if (instance == null) {
synchronized(SongDatabase::class){
instance = Room.databaseBuilder(
context.applicationContext,
SongDatabase::class.java,
"song-database"//다른 데이터 베이스랑 이름겹치면 꼬임
).allowMainThreadQueries().build()
}
}
return instance
}
}
}
데이터베이스를 관리하는 객체이다.
내가 만든 roomDB 는 여러 개의 entity 를 가지기 때문에 콤마로 구분하였고, entity 의 구조가 변경되었을 때 version 을 업그레이드하여 에러가 나지 않도록 한다.
4) 사용
private fun likeAlbum(userId: Int, albumId: Int) {
val songDB = SongDatabase.getInstance(requireContext())!!
val like = Like(userId, albumId)
songDB.albumDao().likeAlbum(like)
}
데이터베이스 사용은 다음과 같다.
아까 생성한 roomDB 의 Instance 를 songDB 라는 변수에 가져온 후,
songDB 의 Dao 에 접근해 Dao 에 구현된 메소드를 통해 데이터베이스에 접근한다.
'안드로이드개발' 카테고리의 다른 글
BottomNavigationView setOnNavigationItemSelectedListener is deprecated (0) | 2022.01.08 |
---|---|
Retrofit2으로 API 서버와 통신 (0) | 2022.01.02 |
Viewpager2 배너 + 자동으로 슬라이딩 구현 (0) | 2022.01.02 |
Fragment 에서 이벤트 발생 시 Activity 에서 발생할 행동 구현하기 (0) | 2022.01.02 |
seekbar 이동시 이벤트 발생(노래 이동) setOnSeekBarChangeListnener (0) | 2022.01.02 |
댓글