안드로이드개발

안드로이드 내부 데이터베이스 roomDB, 테이블(Entity)생성, DAO(메소드)

아뵹젼 2022. 1. 2.

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 에 구현된 메소드를 통해 데이터베이스에 접근한다.

댓글