๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Room - Entity, DAO, Database

interfacer_han 2024. 2. 24. 19:37

Room ๊ฒŒ์‹œ๊ธ€ ์‹œ๋ฆฌ์ฆˆ


#1 ์ด์ „ ๊ธ€

[Android] Room - ๊ธฐ์ดˆ, INSERT์™€ DELETE ์—ฐ์Šต

#1 Room ์†Œ๊ฐœ Room์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ ์ €์žฅ | Android Developers Room ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ• ์•Œ์•„๋ณด๊ธฐ developer.android.com SQLite๋Š” ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ๋ฅผ ์œ„ํ•œ

kenel.tistory.com

๋ณธ ๊ฒŒ์‹œ๊ธ€์€ Room์˜ ๊ธฐ๋ณธ์„ ๋‹ด์€ ์•ฑ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์ด์ „ ๊ฒŒ์‹œ๊ธ€์—์„œ ์ด์–ด์ง„๋‹ค. ์—ฌ๊ธฐ์„œ Room์˜ 3๊ฐ€์ง€ ํ•ต์‹ฌ ํด๋ž˜์Šค์ธ Entity ํด๋ž˜์Šค, DAO ํด๋ž˜์Šค, Database ํด๋ž˜์Šค์˜ ๊ตฌํ˜„์„ ๋‹ค๋ฃฌ๋‹ค. ์ด์ „ ๊ฒŒ์‹œ๊ธ€์—์„œ ๋ชจ๋“ˆ ์ˆ˜์ค€ build.gradle.kts์—์„œ ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ๋ณธ ๊ฒŒ์‹œ๊ธ€์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

#2 Entity, DAO, (Room) Database์˜ ๊ด€๊ณ„

https://developer.android.com/training/data-storage/room

Room Database๋Š” ์ž์‹ ๊ณผ ์—ฐ๊ฒฐ๋œ DAO ์ธ์Šคํ„ด์Šค๋ฅผ Application์— ์ œ๊ณตํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Application์—์„œ DAO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ์˜ ๊ตฌ๋ถ„ ๋‹จ์œ„์ธ Entity์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ฆ‰, INSERT, UPDATE, DELETE ๋ช…๋ น์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์ด๋‹ค.
 

#3 Database์—์„œ ์‚ฌ์šฉํ•  ํ…Œ์ด๋ธ” (Entity ๋””์ž์ธํ•˜๊ธฐ)

 user_iduser_nameuser_email
.........

user_id๊ฐ€ ๊ธฐ๋ณธํ‚ค์ด๊ณ  ์ด 3๊ฐœ์˜ Column์„ ๊ฐ€์ง€๋Š” ํ…Œ์ด๋ธ”์ด๋‹ค. 
 

#4 Entity ํด๋ž˜์Šค ์ƒ์„ฑํ•˜๊ธฐ (User.kt)

// package com.example.roombasics.db

import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "user_data_table")
data class User(

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "user_id")
    val id: Int,

    @ColumnInfo(name = "user_name")
    var name: String,

    @ColumnInfo(name = "user_email")
    var email: String
)

#3์˜ ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ Room Entity ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๋ฉด ์œ„ ์ฝ”๋“œ์™€ ๊ฐ™๋‹ค. ๊ธฐ๋ณธํ‚ค์ธ id๋Š” ํ•œ๋ฒˆ ํ• ๋‹น๋˜๋ฉด ์ดํ›„๋กœ ๋ฐ”๊ฟ€ ์ผ์ด ์—†์œผ๋ฏ€๋กœ val ๋ณ€์ˆ˜๋กœ ๋‘”๋‹ค. ๋ฐ˜๋ฉด, name์ด๋‚˜ email์˜ ๊ฒฝ์šฐ๋Š” UPDATE ์‹œ์— ๋ณ€๊ฒฝ๋  ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ var ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•œ๋‹ค.
 
@PrimaryKey์˜ autoGenerate ์†์„ฑ์ด true๋กœ ์„ค์ •๋˜์–ด์žˆ์œผ๋ฉด, ํ•ด๋‹น Entity์— ๊ธฐ๋ณธํ‚ค๋กœ์„œ์˜ id๊ฐ’์„ ๋ช…์‹œํ•˜์—ฌ INSERTํ•˜์ง€ ์•Š์•„๋„ ์•Œ์•„์„œ id๊ฐ’์„ ์ƒ์„ฑํ•œ๋‹ค. 
 

#5 DAO(Database Access Object Interface) ํด๋ž˜์Šค (UserDAO.kt)

#5-1 ์ฝ”๋“œ

// package com.example.roombasics.db

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update

@Dao
interface UserDAO {

    @Insert
    suspend fun insertUser(user: User): Long

    @Insert(onConflict = OnConflictStrategy.REPLACE) // ์ถฉ๋Œ ์‹œ ๋™์ž‘ ์ •์˜
    suspend fun insertUser2(user: User): Long

    @Insert
    suspend fun insertUser2(user: List<User>): List<Long> // ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋กœ๋”ฉ

    @Insert
    suspend fun insertUser3(user: List<User>): Array<Long>

    @Update
    suspend fun updateUser(user: User)

    @Delete
    suspend fun deleteUser(user: User)

    @Query("INSERT INTO user_data_table (user_name, user_email) VALUES (:name, :email)")
    suspend fun insertUser4(name: String, email: String): Long

    @Query("DELETE FROM user_data_table")
    suspend fun deleteAll()

    @Query("SELECT * FROM user_data_table")
    fun getAllUsers(): LiveData<List<User>>
}

#4์—์„œ ๊ตฌ์„ฑํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋‹ค. Room์€ Annotation์„ ์‹๋ณ„ํ•ด ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์‹ค์ œ ํ•จ์ˆ˜ ์ด๋ฆ„์€ Room์˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, @Insert ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ insertUser() ํ•จ์ˆ˜ ์ด๋ฆ„์„ abcdefg()์™€ ๊ฐ™์ด ์•„๋ฌด๋ ‡๊ฒŒ๋‚˜ ๋ฐ”๊ฟ”๋„ abcdefg() ํ•จ์ˆ˜๋Š” ๊ณ„์† @Insert์˜ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๋˜, ์œ„ ์ฝ”๋“œ์—์„œ ๋ณด๋“ฏ @Insert๋ฅผ ๋ฉ”์†Œ๋“œ ์˜ค๋ฒ„๋กœ๋”ฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ค๋ฒ„๋กœ๋”ฉ๋œ ํ•จ์ˆ˜๋Š” List<User>๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ํ˜•ํƒœ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ Entity๋ฅผ Insertํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

๋˜, ํ•จ์ˆ˜๋“ค์— suspend ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ์ด์œ ๊ฐ€ ์žˆ๋‹ค (suspend ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์ง€ ์•Š์€ getAllUsers()๋Š” #5-6์—์„œ ์„ค๋ช…ํ•จ). Room์€ Main ์Šค๋ ˆ๋“œ์—์„œ Database๋กœ์˜ ์ ‘๊ทผ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ•ด๋‹น ์ž‘์—…์ด Main ์Šค๋ ˆ๋“œ์˜ ์ฃผ์š” ์—ญํ• ์ธ UI ๊ฐฑ์‹ ์„ Blockํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์ด ํ•จ์ˆ˜๋ฅผ Background์—์„œ ๋Œ๋ ค์•ผ ํ•œ๋‹ค ์ฆ‰, ์ฝ”๋ฃจํ‹ด์„ ์ด์šฉํ•ด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
 

#5-2 @Insert ์–ด๋…ธํ…Œ์ด์…˜

Insert๋Š” setter์™€ ๋น„์Šทํ•œ ๋Š๋‚Œ์ด์ง€๋งŒ, return์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€๋ น, Insertํ•œ User์˜ id๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์‹์œผ๋กœ ๋ง์ด๋‹ค. ์ด ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ˜•์€ Room์˜ ์„ค๊ณ„ ์ƒ Long ๋˜๋Š” List<Long>์ด์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. List<Long>์˜ ๊ฒฝ์šฐ 2๊ฐœ ์ด์ƒ์˜ Entity๋ฅผ ๋„ฃ์€ ๊ฒฝ์šฐ์˜ ๋ฐ˜ํ™˜ํ˜•์ด๋‹ค. return์„ ์ƒ๋žต(Unitํ˜•)ํ•ด๋„ ๋œ๋‹ค. ๋ฌผ๋ก  ์ด๋Ÿฌ๋ฉด Insertํ•œ User์˜ id๊ฐ’์„ ์ฐธ์กฐํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ด๋‹ค.
 

OnConflictStrategy  |  Android Developers

androidx.appsearch.builtintypes.properties

developer.android.com

@Insert์™€ @Update ์–ด๋…ธํ…Œ์ด์…˜์—๋Š” onConfilct๋ผ๋Š” ์†์„ฑ์ด ์žˆ๋‹ค. ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ์†์„ฑ์œผ๋กœ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์–ด๋–ค ์ถฉ๋Œ์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ์˜ ๋™์ž‘์„ ์ •์˜ํ•œ๋‹ค. ์ด ์†์„ฑ์— OnConflictStrategy.REPLACE๋ฅผ ํ• ๋‹นํ•˜๋ฉด, (๊ธฐ๋ณธํ‚ค ๋น„๊ต๋กœ) ์ด๋ฏธ ์กด์žฌํ•˜๋Š” Entity๋ฅผ ๋„ฃ์—ˆ์„ ๋•Œ, ์›๋ž˜์˜ Entity๋ฅผ ์‚ญ์ œํ•˜๊ณ  ์ƒˆ๋กœ ๋„ฃ์€ Entity๊ฐ€ ๋Œ€์‹  ๋“ค์–ด๊ฐ„๋‹ค. OnConflictStrategy.IGNORE๋Š” ์ถฉ๋Œ์„ ๋ฌด์‹œํ•œ๋‹ค. ์ฆ‰, ์ƒˆ๋กœ ๋„ฃ์€ Entity๋Š” ๋ฌด์‹œ๋˜๊ณ  ์›๋ž˜ ์žˆ๋˜ Entity๋Š” ๊ณ„์† ์‚ด์•„์žˆ๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  -1์ด ๋ฐ˜ํ™˜๋œ๋‹ค. OnConflictStrategy.ABORT๋Š” ์ถฉ๋Œ์ด ์ผ์–ด๋‚˜๋ฉด Transaction์„ Rollbackํ•œ๋‹ค.
 

#5-3 @Update ์–ด๋…ธํ…Œ์ด์…˜

@Insert์˜ ์„ค๋ช…์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, List๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ 2๊ฐœ ์ด์ƒ์˜ Entity๋ฅผ ํ•œ ๋ฒˆ์— Updateํ•  ์ˆ˜๋„ ์žˆ๊ณ  Update๊ฐ€ ์ˆ˜ํ–‰๋œ Entity์˜ ๊ธฐ๋ณธํ‚ค ๊ฐ’์„ return๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
 

#5-4 @Delete ์–ด๋…ธํ…Œ์ด์…˜

@Insert์˜ ์„ค๋ช…์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, List๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์•„ 2๊ฐœ ์ด์ƒ์˜ Entity๋ฅผ ํ•œ ๋ฒˆ์— Deleteํ•  ์ˆ˜๋„ ์žˆ๊ณ  Delete๊ฐ€ ์ˆ˜ํ–‰๋œ Entity์˜ ๊ธฐ๋ณธํ‚ค ๊ฐ’์„ return๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
 

#5-5 @Query ์–ด๋…ธํ…Œ์ด์…˜

#5-1 ~ #5-3์€ SQLite์˜ Query๋ฌธ์„ ๊ฐ„ํŽธํžˆ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๊ฐ€๊ณต๋œ ํ•จ์ˆ˜๋“ค์˜ ๋‚˜์—ด์ด์—ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, @Insert ์–ด๋…ธํ…Œ์ด์…˜์ด ๋‹ฌ๋ฆฐ InsertUser()๋Š” "INSERT INTO user_data_table (user_name, user_email) VALUES (:name, :email)"๋ผ๋Š” Query๋ฌธ์„ ์ˆ˜ํ–‰ํ•˜๋Š” InsertUser4()์™€ ๊ทธ ๋™์ž‘์ด ๊ฐ™๋‹ค. ์ฆ‰, ๋ณต์žกํ•˜๊ณ  ๋ฒˆ๊ฑฐ๋กœ์šธ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ณธ ๋™์ž‘์„ @Insert๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํ‰์นœ ๊ฒƒ์ด๋‹ค.
 
@Query ์–ด๋…ธํ…Œ์ด์…˜์€ ๊ฐ€๊ณต๋˜์ง€ ์•Š์€ ๋‚  ๊ฒƒ์˜ Query๋ฌธ ์ž์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์กฐ๊ธˆ ๋” ์ง€์—ฝ์ ์ธ, ์กฐ๊ธˆ ๋” ๊ธฐ๋ณธ์ ์ด์ง€ ์•Š์€ ๋™์ž‘์„ @Query ์–ด๋…ธํ…Œ์ด์…˜์— ์ •์˜ํ•œ๋‹ค. ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ํ…Œ์ด๋ธ”์„ ์‚ญ์ œํ•จ์œผ๋กœ์จ ๊ทธ ์†์— ๋‹ด๊ธด ๋ชจ๋“  Entity๋ฅผ Deleteํ•˜๋Š” ๋™์ž‘ ๋“ฑ์„ ์ •์˜ํ–ˆ๋‹ค.
 

#5-6 LiveData์™€ suspend ํ‚ค์›Œ๋“œ์˜ ์ƒ๋žต

getAllUsers()์ฒ˜๋Ÿผ ๋ฐ˜ํ™˜ํ˜•์ด LiveData๋ผ๋ฉด, suspend ํ‚ค์›Œ๋“œ๋ฅผ ์ƒ๋žตํ•œ๋‹ค. ์ƒ๋žตํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š”๋ฐ, ๊ทธ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
 

Dao functions that have a suspend modifier must not return a deferred/async type (androidx.lifecycle.LiveData). Most probably this is an error. Consider changing the return type or removing the suspend modifier.

์—๋Ÿฌ ๋ฉ”์‹œ์ง€์˜ ๋‚ด์šฉ์€ ํ•œ ๋งˆ๋””๋กœ, LiveData๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์— suspend ํ‚ค์›Œ๋“œ๋ฅผ ๋‹ฌ์ง€ ๋ง๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ์™œ๋ƒํ•˜๋ฉด, LiveData๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ์˜ ์—ฐ์†์ ์ธ ํ๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐœ๋…์ด๋‹ค. LiveData๋ผ๋Š” ๊ฐ์ฒด ์ž์ฒด๊ฐ€ ์ด๋ฏธ ๊ทธ ์ž์ฒด๋กœ ๋น„๋™๊ธฐ์ (๋ณ‘๋ ฌ์ )์ธ ๋™์ž‘์„ ๋…๋ฆฝ์ ์œผ๋กœ ๋‚ด์žฌํ•˜๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•จ์ˆ˜์— suspend๋ฅผ ๋ถ™์ผ ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒƒ์ด๋‹ค.
 

#6 Room ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋ž˜์Šค (UserDatabse.kt)

// package com.example.roombasics.db

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {

    abstract val userDAO: UserDAO

    companion object {
        /* @Volatile ์–ด๋…ธํ…Œ์ด์…˜์€ ํด๋ž˜์Šค์˜ ์–ด๋–ค ํ”„๋กœํผํ‹ฐ(ํ•„๋“œ)๊ฐ€ Update๋์„ ๋•Œ,
         * ๊ทธ ๊ฐฑ์‹ ๋œ ๊ฐ’์„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๋ฐ”๋กœ ์ฝ๊ฒŒ(= ์บ์‹œ๊ฐ€ ์•„๋‹Œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฝ๊ฒŒ) ํ•œ๋‹ค.
         * ์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ์—†๋‹ค๋ฉด, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ๊ฐฑ์‹  ์ด์ „์˜ ๊ฐ’์œผ๋กœ ์ž˜๋ชป ์ฝ์„ ์ˆ˜๋„ ์žˆ๋‹ค.
         * ์บ์‹œ์—๋Š” ์‹œ์ฐจ๊ฐ€ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
         */
        @Volatile
        private var INSTANCE: UserDatabase? = null
        fun getInstance(context: Context): UserDatabase {
            synchronized(this) {
                var instance = INSTANCE
                if (instance == null) {
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        UserDatabase::class.java,
                        "user_data_database"
                    ).build()
                    INSTANCE = instance
                }
                return instance
            }
        }
    }
}

Entity ํด๋ž˜์Šค์™€ ํ•ด๋‹น Entity๋ฅผ ๋‹ค๋ฃจ๋Š” DAO ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ๋‹ค. ๋‚จ์€ ๊ฒƒ์€ Application์— ํƒ‘์žฌ๋œ ์‹ค์ œ Database๋ฅผ ๋Œ€๋ณ€ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค. ๋จผ์ € @Database ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜, ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์‚ฌ์šฉํ•  Entity ํด๋ž˜์Šค ๊ทธ๋ฆฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฒ„์ „์„ ์ ๋Š”๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฒ„์ „์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์œ ์ง€๋ณด์ˆ˜ํ•˜๋ฉด์„œ ํ•˜๋‚˜์”ฉ ์˜ฌ๋ ค๊ฐ€๋Š” ์ˆซ์ž๋‹ค. ์ง€๊ธˆ์€ ์ฒ˜์Œ ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ 1์ด๋ผ๊ณ  ์ ์—ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋กœ DAO๋„ ์ถ”๊ฐ€ํ•œ๋‹ค. DAO๋Š” ์ด Database ํด๋ž˜์Šค์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•œ ์ง„์ž…๋ฌธ ์—ญํ• ์„ ํ•œ๋‹ค.
 
companion object { ... }๋ฅผ ๋ณด๋ฉด ์ด Database ํด๋ž˜์Šค๋ฅผ Singleton ํŒจํ„ด์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. Database ๊ฐ์ฒด๋Š” ๊ตณ์ด ํ•˜๋‚˜ ์ด์ƒ ๋งŒ๋“ค์–ด์งˆ ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด์ „ ๋ฌธ์žฅ์˜ ์œ„ํ‚ค๋ฐฑ๊ณผ ๋งํฌ์—์„œ, ์ฝ”ํ‹€๋ฆฐ์—์„œ์˜ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด ์˜ˆ์‹œ๊ฐ€ object ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•ด ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๋กœ ์ ํ˜€์žˆ๋‹ค. ํ•˜์ง€๋งŒ, @Database๋Š” abstract class๋กœ object๊ฐ€ ์•„๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ companion object { ... }๋ฅผ ์ด์šฉํ•ด ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์„ ๊ตฌํ˜„ํ–ˆ๋‹ค. object ํ‚ค์›Œ๋“œ ๋ฒ„์ „์— ๋น„ํ•ด ๋” ๋ณต์žกํ•˜์ง€๋งŒ, ์–ด์ฉ” ์ˆ˜ ์—†๋‹ค.
 
์œ„ ์ฝ”๋“œ๋Š” Room์˜ @Database๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋‹ค๋ฅธ ๋งŽ์€ ํ”„๋กœ์ ํŠธ๋“ค๋„ ๋˜‘๊ฐ™์ด ์‚ฌ์šฉ๋œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ๋ฅผ ์ž์ฃผํ•˜๊ฒŒ ๋  ์ฝ”๋“œ๋กœ ๋ณด์ธ๋‹ค.
 

#7 ์š”์•ฝ

Entity๋Š” ๋ฐ์ดํ„ฐ, Database๋Š” ๋ง ๊ทธ๋Œ€๋กœ Base, DAO๋Š” ๊ทธ ๋‘˜์„ ์ž‡๋Š” ๊ด€๋ฌธ์ด๋‹ค.
 

#8 ๋‹ค์‹œ ์ด์ „๊ธ€๋กœ

[Android] Room - ๊ธฐ์ดˆ, INSERT์™€ DELETE ์—ฐ์Šต

#1 Room ์†Œ๊ฐœ Room์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ฐ์ดํ„ฐ ์ €์žฅ | Android Developers Room ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ• ์•Œ์•„๋ณด๊ธฐ developer.android.com SQLite๋Š” ๋ชจ๋ฐ”์ผ ๊ธฐ๊ธฐ๋ฅผ ์œ„ํ•œ

kenel.tistory.com

๋‹ค์‹œ ์ด์ „ ๊ธ€๋กœ ๋Œ์•„๊ฐ€ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ๊ตฌํ˜„ํ•ด๋‚˜๊ฐ„๋‹ค.