Room 지속성 라이브러리는 SQLite를 통해 추상화 레이어를 제공하여 을 사용하여 SQLite를 완벽히 활용하면서 더 강력한 데이터베이스 액세스를 제공합니다. 이 페이지는 Kotlin 멀티플랫폼 (KMP) 프로젝트에서 Room을 사용하는 데 중점을 둡니다. 자세한 내용은 Room 사용에 관한 자세한 내용은 Room을 사용하여 로컬 데이터베이스에 데이터 저장을 참고하세요. 또는 공식 샘플을 참고하세요.
종속 항목 설정
KMP를 지원하는 Room의 현재 버전은 다음과 같습니다. 2.7.0-alpha01 이상
KMP 프로젝트에서 Room을 설정하려면
build.gradle.kts
파일을 생성합니다.
androidx.room:room-gradle-plugin
- Room 스키마를 구성하는 Gradle 플러그인androidx.room:room-compiler
- 코드를 생성하는 KSP 프로세서androidx.room:room-runtime
- 라이브러리의 런타임 부분androidx.sqlite:sqlite-bundled
- (선택사항) 번들 SQLite 라이브러리
또한 Room의 SQLite 드라이버를 구성해야 합니다. 이러한 요인은 기반으로 작동합니다 자세한 내용은 드라이버 구현 을 참조하세요.
추가 설정 정보는 다음을 참고하세요.
를 통해 개인정보처리방침을 정의할 수 있습니다.데이터베이스 클래스 정의
DAO와 함께 @Database
주석이 달린 데이터베이스 클래스를 만들어야 함
및 개체와 함께 공유 KMP 모듈의 공통 소스 세트에 포함되어 있습니다. 배치
공통 소스에 있는 이러한 클래스를 사용하면 모든 대상 간에 공유될 수 있습니다.
지원합니다
인터페이스로 expect
객체를 선언하는 경우
RoomDatabaseConstructor
: Room 컴파일러가 actual
있습니다. Android 스튜디오에서 경고가 발생할 수 있음
"Expected object 'AppDatabaseConstructor' has no actual declaration in module";
you can suppress the warning with
@Suppress("NO_ACTUAL_FOR_EXPECT")`와 같은 형식입니다.
// shared/src/commonMain/kotlin/Database.kt
@Database(entities = [TodoEntity::class], version = 1)
@ConstructedBy(AppDatabaseConstructor::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun getDao(): TodoDao
}
// The Room compiler generates the `actual` implementations.
@Suppress("NO_ACTUAL_FOR_EXPECT")
expect object AppDatabaseConstructor : RoomDatabaseConstructor<AppDatabase>
@Dao
interface TodoDao {
@Insert
suspend fun insert(item: TodoEntity)
@Query("SELECT count(*) FROM TodoEntity")
suspend fun count(): Int
@Query("SELECT * FROM TodoEntity")
fun getAllAsFlow(): Flow<List<TodoEntity>>
}
@Entity
data class TodoEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val title: String,
val content: String
)
실제 / 예상 선언을 선택적으로 사용할 수 있습니다.
을 사용하여 플랫폼별 Room 구현을 만듭니다. 예를 들어
expect
를 사용하여 공통 코드에 정의된 플랫폼별 DAO
플랫폼별 추가 쿼리로 actual
정의 지정
소스 세트입니다.
데이터베이스 빌더 만들기
데이터베이스 빌더를 정의하여 각 플랫폼에서 Room을 인스턴스화해야 합니다. 이
API에서 플랫폼별 소스에 있어야 하는 유일한 부분임
파일 시스템 API의 차이로 인해 발생합니다. 예를 들어 Android에서
데이터베이스 위치는 일반적으로
Context.getDatabasePath()
API, iOS의 경우 데이터베이스 위치는
NSFileManager
를 사용하여 얻습니다.
Android
데이터베이스 인스턴스를 만들려면 데이터베이스와 함께 컨텍스트를 지정합니다. 있습니다.
// shared/src/androidMain/kotlin/Database.kt
fun getDatabaseBuilder(ctx: Context): RoomDatabase.Builder<AppDatabase> {
val appContext = ctx.applicationContext
val dbFile = appContext.getDatabasePath("my_room.db")
return Room.databaseBuilder<AppDatabase>(
context = appContext,
name = dbFile.absolutePath
)
}
iOS
데이터베이스 인스턴스를 만들려면 다음을 사용하여 데이터베이스 경로를 제공합니다.
NSFileManager
. 일반적으로 NSDocumentDirectory
에 있습니다.
// shared/src/iosMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFilePath = documentDirectory() + "/my_room.db"
return Room.databaseBuilder<AppDatabase>(
name = dbFilePath,
)
}
private fun documentDirectory(): String {
val documentDirectory = NSFileManager.defaultManager.URLForDirectory(
directory = NSDocumentDirectory,
inDomain = NSUserDomainMask,
appropriateForURL = null,
create = false,
error = null,
)
return requireNotNull(documentDirectory?.path)
}
JVM (데스크톱)
데이터베이스 인스턴스를 만들려면 Java 또는 Kotlin을 사용하여 데이터베이스 경로를 제공하세요. API에 액세스할 수 있습니다
// shared/src/jvmMain/kotlin/Database.kt
fun getDatabaseBuilder(): RoomDatabase.Builder<AppDatabase> {
val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db")
return Room.databaseBuilder<AppDatabase>(
name = dbFile.absolutePath,
)
}
데이터베이스 인스턴스화
플랫폼별 중 하나에서 RoomDatabase.Builder
를 가져온 후
Room 데이터베이스의 나머지 부분을 공통 코드로 구성할 수 있습니다.
실제 데이터베이스 인스턴스화와 함께 제공됩니다.
// shared/src/commonMain/kotlin/Database.kt
fun getRoomDatabase(
builder: RoomDatabase.Builder<AppDatabase>
): AppDatabase {
return builder
.addMigrations(MIGRATIONS)
.fallbackToDestructiveMigrationOnDowngrade()
.setDriver(BundledSQLiteDriver())
.setQueryCoroutineContext(Dispatchers.IO)
.build()
}
SQLiteDriver 선택
이전 코드 스니펫은 BundledSQLiteDriver
를 사용합니다. 이것은
SQLite를 포함하는 것이 좋습니다. 이 드라이버는
가장 일관성 있는 최신 버전의 SQLite를 시킵니다. 만약
OS에서 제공하는 SQLite를 사용하려면 플랫폼별 setDriver
API를 사용하세요.
플랫폼별 드라이버를 지정하는 소스 세트를 생성합니다. Android의 경우
AndroidSQLiteDriver
, iOS의 경우 NativeSQLiteDriver
를 사용할 수 있습니다. 받는사람
NativeSQLiteDriver
를 사용하는 경우 iOS 기기에서
앱이 시스템 SQLite와 동적으로 링크됩니다.
// shared/build.gradle.kts
kotlin {
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "TodoApp"
isStatic = true
// Required when using NativeSQLiteDriver
linkerOpts.add("-lsqlite3")
}
}
}
차이점
Room은 원래 Android 라이브러리로 개발되었으며 나중에 API 호환성에 중점을 둔 KMP Room의 KMP 버전은 약간 다릅니다. Android 전용 버전에서 달라질 수 있습니다 이러한 차이점은 나열되고 설명되어 있습니다.
DAO 함수 차단
KMP용 Room을 사용할 때 Android가 아닌 플랫폼용으로 컴파일된 모든 DAO 함수
suspend
함수여야 합니다. 단, 반응형 반환 유형은 예외입니다.
Flow
형식으로 전송합니다.
// shared/src/commonMain/kotlin/MultiplatformDao.kt
@Dao
interface MultiplatformDao {
// ERROR: Blocking function not valid for non-Android targets
@Query("SELECT * FROM Entity")
fun blockingQuery(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
suspend fun query(): List<Entity>
// OK
@Query("SELECT * FROM Entity")
fun queryFlow(): Flow<List<Entity>>
// ERROR: Blocking function not valid for non-Android targets
@Transaction
fun blockingTransaction() { // … }
// OK
@Transaction
suspend fun transaction() { // … }
}
Room에서 제공하는 기능이 풍부한 비동기 kotlinx.coroutines
라이브러리의 이점
다양한 플랫폼에서 사용할 수 있습니다 최적의 기능을 위해 suspend
함수가 KMP 프로젝트에서 컴파일된 DAO에 적용되지만
기존 DAO와의 하위 호환성을 유지하기 위한 Android 관련 DAO
제공합니다
KMP와의 기능 차이
이 섹션에서는 KMP와 Android 플랫폼 간 기능의 차이점을 설명합니다. 맞춤설정할 수 있습니다.
@RawQuery DAO 함수
Android가 아닌 플랫폼용으로 컴파일된 @RawQuery
주석이 달린 함수
는RoomRawQuery
SupportSQLiteQuery
입니다.
@Dao
interface TodoDao {
@RawQuery
suspend fun getTodos(query RoomRawQuery): List<TodoEntity>
}
그런 다음 RoomRawQuery
를 사용하여 런타임에 쿼리를 만들 수 있습니다.
suspend fun getTodosWithLowercaseTitle(title: String): List<TodoEntity> {
val query = RoomRawQuery(
sql = "SELECT * FROM TodoEntity WHERE title = ?"
onBindStatement = {
it.bindText(1, title.lowercase())
}
)
return todosDao.getTodos(query)
}
콜백 쿼리
쿼리 콜백 구성을 위한 다음 API는 일반적으로 사용할 수 없습니다. 따라서 Android 이외의 플랫폼에서는 사용할 수 없습니다.
RoomDatabase.Builder.setQueryCallback
RoomDatabase.QueryCallback
Room의 향후 버전에서 쿼리 콜백 지원을 추가할 예정입니다.
쿼리 콜백으로 RoomDatabase
를 구성하는 API
RoomDatabase.Builder.setQueryCallback
및 콜백 인터페이스
RoomDatabase.QueryCallback
는 공통으로 사용할 수 없으므로 사용할 수 없습니다.
다른 플랫폼에서도 작동합니다.
데이터베이스 자동 닫기
제한 시간 후 자동 닫기를 사용 설정하는 API
RoomDatabase.Builder.setAutoCloseTimeout
은(는) Android에서만 사용할 수 있으며 현재
다른 플랫폼에서는 이용할 수 없습니다.
사전 패키지 데이터베이스
다음 API는 기존 데이터베이스 (예:RoomDatabase
사전 패키징된 데이터베이스)는 공통으로 사용할 수 없으므로
다른 플랫폼에서도 사용할 수 있습니다. 이러한 API는 다음과 같습니다.
RoomDatabase.Builder.createFromAsset
RoomDatabase.Builder.createFromFile
RoomDatabase.Builder.createFromInputStream
RoomDatabase.PrepackagedDatabaseCallback
Google은 방.
멀티 인스턴스 무효화
멀티 인스턴스 무효화를 사용 설정하는 API
RoomDatabase.Builder.enableMultiInstanceInvalidation
은(는) 다음에서만 사용할 수 있습니다.
일반적인 플랫폼이나 다른 플랫폼에서는 사용할 수 없습니다.