DBILITY

android room database 본문

android/kotlin

android room database

DBILITY 2024. 3. 29. 11:49
반응형

https://developer.android.com/codelabs/basic-android-kotlin-compose-persisting-data-room?hl=ko#0

 

Room을 사용하여 데이터 유지  |  Android Developers

Android Kotlin 앱에서 Room을 사용하는 방법을 알아보세요. Room은 Android Jetpack의 일부인 지속성 데이터베이스 라이브러리로, SQLite 위에 있는 추상화 레이어입니다. Room은 데이터베이스를 설정하고 구

developer.android.com

안드로이드에서 제공하는 SQLite JPA로 생각하면 된다.

Entity > Dao > Database(Helper라고 생각하자) 순으로 만들면 된다.

Log.d("getDatabasePath",getDatabasePath("room_db").absoluteFile.toString())

위와 같이 생성된 경로를 확인 가능하다.

저장 경로가 /data/user/0/패키지경로/databases 로 나온다.

실제로 보니 data/user/0 = data/data 다 avd device explorer에서 찾아보자

room_db ,room_db-shm, room_db-wal 파일 세개가 생성되어 있다.

device explorer에서 외부로 3개파일을 복사 후 sql tool로 보면 데이터가 보인다.

ViewModel에서 연동(?)하면 되겠다.

Entity

package com.dbility.myroom

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

@Entity(tableName = "room_memo")
data class RoomMemo(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo var no: Long = 0,
    @ColumnInfo val content: String,
    @ColumnInfo val datetime: Long
)

Dao

package com.dbility.myroom

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow

@Dao
interface RoomMeoDao {

    @Query("SELECT * FROM room_memo")
    fun getAll(): Flow<List<RoomMemo>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(roomMemo: RoomMemo): Long

    @Delete
    suspend fun delete(roomMemo: RoomMemo) : Int

    @Update
    suspend fun update(roomMemo: RoomMemo) : Int

}

Database Helper

package com.dbility.myroom

import androidx.room.Database
import androidx.room.RoomDatabase

@Database(entities = [RoomMemo::class], version = 1, exportSchema = false)
abstract class RoomMemoHelper : RoomDatabase() {
    abstract fun roomMeoDao(): RoomMeoDao
}

ViewModel

package com.dbility.myroom

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.util.Calendar
import java.util.Locale

class RoomViewModel(helper: RoomMemoHelper) : ViewModel() {

    private val _items = MutableStateFlow<List<RoomMemo>>(emptyList())
    val items: StateFlow<List<RoomMemo>> = _items
    private val dao: RoomMeoDao = helper.roomMeoDao()
    var selectedNo: Long? = null

    init {
        viewModelScope.launch {
            dao.getAll().collect {
                _items.value = it
            }
        }
    }

    fun insert(content: String): Long {
        var affectedRow = 0L
        viewModelScope.launch {
            val roomMemo = RoomMemo(
                0,
                content,
                Calendar.getInstance(Locale.getDefault()).timeInMillis
            )
            affectedRow = dao.insert(roomMemo)
            //Log.d("affectedRow", affectedRow.toString())
        }
        return affectedRow
    }

    fun update(content: String) {
        viewModelScope.launch {
            Log.d("viewModel.selectedNo", selectedNo.toString())
            dao.update(
                RoomMemo(
                    selectedNo!!,
                    content,
                    Calendar.getInstance(Locale.getDefault()).timeInMillis
                )
            )
            selectedNo = null
        }
    }

    fun delete(roomMemo: RoomMemo) {
        viewModelScope.launch {
            _items.value.find { value -> value.no == roomMemo.no }
                ?.let { roomMemo -> dao.delete(roomMemo) }
            selectedNo = null
        }
    }
}

class RoomViewModelFactory(private val helper: RoomMemoHelper) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return if (modelClass.isAssignableFrom(RoomViewModel::class.java)) {
            RoomViewModel(helper) as T
        } else {
            throw IllegalArgumentException()
        }
    }
}

정확한 건 더 학습이 필요하지만 무튼 되긴 한다.


class MainActivity : AppCompatActivity() {

    private val binding by lazy {
        ActivityMainBinding.inflate(layoutInflater)
    }
    private lateinit var helper: RoomMemoHelper
    private lateinit var viewModel: RoomViewModel
    private val memoListAdapter = MemoListAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        .......        
        helper = Room.databaseBuilder(this, RoomMemoHelper::class.java, "room_db")
            .allowMainThreadQueries()//학습시만
            .build()

        viewModel = ViewModelProvider(this, RoomViewModelFactory(helper))[RoomViewModel::class.java]

        with(binding) {
            lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    viewModel.items.collect {
                        memoListAdapter.submitList(it)
                        Log.d("collect", it.toString())
                    }
                }
            }            
        }
    }
}
반응형

'android > kotlin' 카테고리의 다른 글

android dark mode 비활성화  (0) 2024.04.04
android retrofit2  (0) 2024.04.01
android viewmodel 에서 constructor arguments  (0) 2024.03.29
android migration kapt to ksp  (0) 2024.03.29
안드로이드 SQLiteOpenHelper 구현  (0) 2024.03.28
Comments