Android

Android - Room 라이브러리로 SQLite 데이터베이스 구축 및 CRUD 구현하기

임베디드 친구 2024. 11. 21. 14:31
반응형

안드로이드 애플리케이션을 개발하다 보면 데이터의 영속성을 유지하기 위해 데이터베이스를 사용해야 하는 경우가 많습니다. 안드로이드에서는 대표적으로 SQLite 데이터베이스를 사용할 수 있지만, SQLite API를 직접 사용하는 것은 불편하고 에러가 발생하기 쉽습니다. 이를 좀 더 편리하게 사용할 수 있도록 구글에서 제공하는 Room 라이브러리를 활용하면 좋습니다. 이번 포스팅에서는 Room을 이용해 SQLite 데이터베이스를 구축하고, CRUD (Create, Read, Update, Delete) 작업을 구현하는 방법을 예제를 통해 소개하겠습니다.

Room 라이브러리란?

Room은 안드로이드 Jetpack 라이브러리의 일부로, SQLite 데이터베이스에 접근하기 위한 추상화 계층을 제공합니다. Room을 사용하면 SQL 쿼리를 직접 작성하는 대신 더 간결한 코드를 작성할 수 있으며, 컴파일 시간에 SQL 쿼리를 검사해 주기 때문에 런타임 오류를 줄일 수 있습니다.

주요 컴포넌트

Room은 다음과 같은 주요 컴포넌트로 구성됩니다:

  • Entity: 데이터베이스 테이블을 나타내는 클래스입니다.
  • DAO (Data Access Object): 데이터베이스에 접근하기 위한 인터페이스로, SQL 쿼리를 메서드로 정의합니다.
  • Database: RoomDatabase를 상속받아 데이터베이스를 생성하고 DAO를 제공합니다.

Room 설정하기

먼저, 프로젝트에 Room 라이브러리를 추가해야 합니다. build.gradle 파일에 다음과 같이 Room 라이브러리 의존성을 추가합니다.

dependencies {
    implementation "androidx.room:room-runtime:2.4.2"
    kapt "androidx.room:room-compiler:2.4.2"
}

이제 Room을 사용하여 SQLite 데이터베이스를 구축해 보겠습니다.

Room 구성 요소 생성하기

1. Entity 생성

Entity는 데이터베이스 테이블을 나타내며, 각 테이블의 열은 클래스의 필드로 정의됩니다. 아래 예제에서는 User 엔티티를 정의합니다.

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

@Entity(tableName = "user_table")
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val name: String,
    val age: Int
)
  • @Entity 어노테이션을 사용하여 테이블을 정의합니다.
  • @PrimaryKey 어노테이션은 기본 키를 나타내며, autoGeneratetrue로 설정하여 자동으로 생성되도록 합니다.

2. DAO (Data Access Object) 생성

DAO는 데이터베이스에 접근하는 인터페이스로, 데이터 조작 메서드를 정의합니다.

import androidx.room.*

@Dao
interface UserDao {
    @Insert
    suspend fun insert(user: User)

    @Update
    suspend fun update(user: User)

    @Delete
    suspend fun delete(user: User)

    @Query("SELECT * FROM user_table ORDER BY id ASC")
    suspend fun getAllUsers(): List<User>
}
  • @Dao 어노테이션을 사용하여 DAO 인터페이스를 정의합니다.
  • @Insert, @Update, @Delete 어노테이션을 사용하여 기본적인 CRUD 작업을 구현할 수 있습니다.
  • @Query 어노테이션을 통해 커스텀 쿼리를 정의할 수 있습니다.

3. RoomDatabase 생성

이제 RoomDatabase를 상속받아 데이터베이스를 생성합니다.

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

@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class UserDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}
  • @Database 어노테이션을 사용하여 데이터베이스 클래스를 정의합니다.
  • entities 매개변수에 데이터베이스에 포함될 엔티티들을 지정합니다.
  • UserDao를 반환하는 추상 메서드를 정의합니다.

데이터베이스 인스턴스 생성

RoomDatabase 인스턴스를 생성하려면 보통 Singleton 패턴을 사용하여 앱 전체에서 하나의 인스턴스만 존재하도록 합니다.

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

object DatabaseBuilder {
    @Volatile
    private var INSTANCE: UserDatabase? = null

    fun getInstance(context: Context): UserDatabase {
        return INSTANCE ?: synchronized(this) {
            val instance = Room.databaseBuilder(
                context.applicationContext,
                UserDatabase::class.java,
                "user_database"
            ).build()
            INSTANCE = instance
            instance
        }
    }
}

CRUD 구현하기

이제 ViewModel과 연결하여 CRUD 작업을 구현해 보겠습니다.

1. UserViewModel 생성

ViewModel을 사용하여 데이터를 관리하고, View와 데이터베이스 간의 연결을 유지합니다.

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class UserViewModel(private val userDao: UserDao) : ViewModel() {

    fun insert(user: User) {
        viewModelScope.launch {
            userDao.insert(user)
        }
    }

    fun update(user: User) {
        viewModelScope.launch {
            userDao.update(user)
        }
    }

    fun delete(user: User) {
        viewModelScope.launch {
            userDao.delete(user)
        }
    }

    fun getAllUsers() {
        viewModelScope.launch {
            val users = userDao.getAllUsers()
            // 가져온 사용자 목록을 UI에 반영합니다.
        }
    }
}
  • viewModelScope를 사용하여 코루틴을 실행하고, 백그라운드 스레드에서 DAO 메서드를 호출합니다.

UI 구현하기

마지막으로, 사용자 인터페이스를 구현하여 CRUD 작업을 실행할 수 있는 화면을 만들어 보겠습니다. 아래 예제에서는 간단한 RecyclerView를 사용하여 사용자 목록을 표시합니다.

1. UserAdapter 생성

RecyclerView 어댑터를 사용하여 사용자 목록을 표시합니다.

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.app.databinding.ItemUserBinding

class UserAdapter(private val users: List<User>) : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {

    inner class UserViewHolder(private val binding: ItemUserBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(user: User) {
            binding.textViewName.text = user.name
            binding.textViewAge.text = user.age.toString()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
        val binding = ItemUserBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return UserViewHolder(binding)
    }

    override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
        holder.bind(users[position])
    }

    override fun getItemCount(): Int = users.size
}
  • UserAdapter 클래스는 User 목록을 RecyclerView에 표시합니다.
  • ItemUserBinding을 사용하여 각 항목의 뷰를 설정합니다.

정리

이번 포스팅에서는 Room 라이브러리를 사용하여 안드로이드에서 SQLite 데이터베이스를 구축하고, CRUD 작업을 구현하는 방법을 살펴보았습니다. Room을 사용하면 데이터베이스 관련 코드를 간결하게 작성할 수 있고, 컴파일 시간에 SQL 쿼리를 검사해 주기 때문에 더욱 안전하게 개발할 수 있습니다.

주요 코드 요약

  • Entity: 데이터베이스 테이블을 나타내는 클래스.
  • DAO: 데이터 접근 메서드를 정의한 인터페이스.
  • RoomDatabase: 데이터베이스 인스턴스를 생성하는 클래스.
  • ViewModel: UI와 데이터베이스 간의 연결을 유지하며 데이터를 관리.

Room 라이브러리를 통해 안드로이드 앱에서 데이터베이스 작업을 간단하고 안전하게 처리해 보세요! 추가적인 질문이나 다른 예제가 필요하다면 언제든지 댓글로 알려주세요.

반응형