DB + SQL
Android에서 로컬 데이터베이스 접근하기
dev_SiWoo
2025. 10. 24. 18:08
Android에서 sqlite3와 같은 로컬 DB를 사용해야하는 상황을 직면했다.
이 때, 보통 Spring에서 사용하는 Mybatis와 같은 서버측 ORM 프레임워크와 비슷하게 DB에 접근하여 ORM 역할을 학는 공식 라이브러리 중 최신 표준이라고 하는 Room Persistence Library가 존재하였다.
Room Persistence Library는 현재 안드로이드 앱 개발에서 가장 권장되는 방법이자, MyBatis와 같은 ORM의 역할을 대신하는 공식 라이브러리라고한다.
SQLite 위에 추상화 계층을 제공하여 SQL쿼리를 컴파일 시점에 검사하고, 복잡한 보일러 플레이코드를 줄여준다고한다.
1. Entity(테이블 정의)
// InspectionItem.kt
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "inspection_items") // 💡 테이블 이름 지정
data class InspectionItem(
// 💡 Primary Key 지정 및 Auto-generation 설정 (필요에 따라)
@PrimaryKey(autoGenerate = true)
val itemId: Int = 0,
// 테이블의 컬럼들
val name: String,
val status: String,
val inspectorId: Int
)
2. DAO (Data Access Object)
// InspectionItemDao.kt
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import androidx.room.Delete
import kotlinx.coroutines.flow.Flow
@Dao
interface InspectionItemDao {
// 💡 모든 항목을 조회하는 쿼리
@Query("SELECT * FROM inspection_items ORDER BY itemId DESC")
fun getAllItems(): Flow<List<InspectionItem>> // Flow는 실시간 업데이트를 지원
// 💡 특정 검사원의 항목만 조회하는 쿼리
@Query("SELECT * FROM inspection_items WHERE inspectorId = :id")
suspend fun getItemsByInspector(id: Int): List<InspectionItem>
// 💡 새 항목을 삽입하는 메서드
@Insert
suspend fun insert(item: InspectionItem)
// 💡 항목을 업데이트하는 메서드
@Update
suspend fun update(item: InspectionItem)
// 💡 항목을 삭제하는 메서드
@Delete
suspend fun delete(item: InspectionItem)
// 💡 모든 데이터를 삭제하는 쿼리 (동기화 시 유용)
@Query("DELETE FROM inspection_items")
suspend fun deleteAll()
}
3. Database (DB 생성 및 버전 관리)
// AppDatabase.kt
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
// 💡 데이터베이스에 포함될 모든 Entity와 버전을 지정
@Database(entities = [InspectionItem::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
// 💡 DAO에 접근할 수 있는 추상 메서드
abstract fun itemDao(): InspectionItemDao
// 싱글톤 패턴을 위한 Companion Object
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
// INSTANCE가 null이 아닐 경우, 반환
// null일 경우, 데이터베이스를 생성 (synchronized로 스레드 안전성 확보)
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"inspection_db" // 💡 SQLite 파일 이름
).build()
INSTANCE = instance
instance
}
}
}
}