Room 3.0

  
Thư viện lưu trữ Room cung cấp một lớp trừu tượng qua SQLite để mang lại khả năng truy cập cơ sở dữ liệu mạnh mẽ hơn, đồng thời khai thác toàn bộ sức mạnh của SQLite.
Bản cập nhật mới nhất Bản phát hành ổn định Bản phát hành dùng thử Bản phát hành beta Bản phát hành alpha
Ngày 11 tháng 3 năm 2026 - - - 3.0.0-alpha01

Khai báo phần phụ thuộc

Để thêm một phần phụ thuộc trên Room3, bạn phải thêm kho lưu trữ Google Maven vào dự án. Đọc nội dung Kho lưu trữ Maven của Google để biết thêm thông tin.

Thêm các phần phụ thuộc cho cấu phần phần mềm bạn cần trong tệp build.gradle cho ứng dụng hoặc mô-đun của mình:

Kotlin

dependencies {
    val room_version = ""

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

Groovy

dependencies {
    def room_version = ""

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

Để biết thông tin về cách sử dụng trình bổ trợ KSP, hãy xem tài liệu bắt đầu nhanh về KSP.

Để biết thêm thông tin về các phần phụ thuộc, hãy xem nội dung Thêm phần phụ thuộc cho bản dựng.

Sử dụng trình bổ trợ Room cho Gradle

Bạn có thể sử dụng trình bổ trợ Room cho Gradle để định cấu hình các lựa chọn cho trình biên dịch Room. Trình bổ trợ này định cấu hình dự án sao cho các giản đồ đã tạo (là đầu ra của các tác vụ biên dịch và được sử dụng cho quá trình di chuyển tự động) được định cấu hình chính xác để có các bản dựng có thể tái tạo và lưu vào bộ nhớ đệm.

Để thêm trình bổ trợ này, trong tệp bản dựng Gradle cấp cao nhất, hãy xác định trình bổ trợ và phiên bản của trình bổ trợ.

Groovy

plugins {
    id 'androidx.room3' version "$room_version" apply false
}

Kotlin

plugins {
    id("androidx.room3") version "$room_version" apply false
}

Trong tệp bản dựng Gradle cấp mô-đun, hãy áp dụng trình bổ trợ và sử dụng tiện ích room3.

Groovy

plugins {
    id 'androidx.room3'
}

room3 {
    schemaDirectory "$projectDir/schemas"
}

Kotlin

plugins {
    id("androidx.room3")
}

room3 {
    schemaDirectory("$projectDir/schemas")
}

Bạn phải đặt schemaDirectory khi sử dụng trình bổ trợ Room cho Gradle. Thao tác này sẽ định cấu hình trình biên dịch Room và các tác vụ biên dịch cũng như các phần phụ trợ (kotlinc, KSP) để xuất tệp giản đồ vào các thư mục theo phiên bản, chẳng hạn như schemas/flavorOneDebug/com.package.MyDatabase/1.json. Bạn nên kiểm tra các tệp này trong kho lưu trữ để dùng cho quá trình xác thực và di chuyển tự động.

Phản hồi

Ý kiến phản hồi của bạn có thể giúp chúng tôi cải thiện Jetpack. Hãy cho chúng tôi biết nếu bạn phát hiện lỗi mới hoặc có ý tưởng cải thiện thư viện này. Vui lòng xem các lỗi hiện có trong thư viện này trước khi báo một lỗi mới. Bạn có thể thêm lượt bình chọn cho lỗi hiện có bằng cách nhấp vào nút dấu sao.

Báo lỗi mới

Xem tài liệu về Công cụ theo dõi lỗi để biết thêm thông tin.

Phiên bản 3.0

Phiên bản 3.0.0-alpha01

Ngày 11 tháng 3 năm 2026

Phát hành androidx.room3:room3-*:3.0.0-alpha01.

Room 3.0 (gói androidx.room3) là một bản cập nhật phiên bản lớn của gói Room 2.x (androidx.room) tập trung vào Kotlin Multiplatform (KMP).

Các API chú thích cốt lõi vẫn giữ nguyên cùng với các thành phần chính:

  • Một lớp trừu tượng mở rộng androidx.room3.RoomDatabase và được chú thích bằng @Database là điểm truy cập cho trình xử lý chú giải của Room.
  • Khai báo cơ sở dữ liệu có một hoặc nhiều lớp dữ liệu mô tả giản đồ cơ sở dữ liệu và được chú thích bằng @Entity.
  • Các thao tác trên cơ sở dữ liệu được xác định trong các khai báo @Dao chứa các hàm truy vấn có câu lệnh SQL được xác định thông qua chú thích @Query.
  • Trong thời gian chạy, bạn có thể nhận được quá trình triển khai cơ sở dữ liệu thông qua RoomDatabase.Builder. RoomDatabase.Builder này cũng được dùng để định cấu hình cơ sở dữ liệu.

Hầu hết tài liệu trong hướng dẫn Lưu dữ liệu trong cơ sở dữ liệu cục bộ bằng Room vẫn liên quan đến Room 3.0.

Dưới đây là những điểm khác biệt chính gây ảnh hưởng đến khả năng tương thích giữa Room 2.x:

  • Gói mới, androidx.room3.
  • Các API SupportSQLite không còn được hỗ trợ nữa, trừ phi bạn đang sử dụng androidx.room3:room3-sqlite-wrapper.
  • Tất cả các thao tác về cơ sở dữ liệu hiện đều dựa trên Coroutine API.
  • Chỉ tạo mã Kotlin.
  • Bạn phải dùng Kotlin Symbol Processing (KSP).

Ngoài những thay đổi có thể gây lỗi, Room 3.0 còn mang đến chức năng mới so với phiên bản 2.x:

  • Hỗ trợ JS và WasmJS
  • Loại dữ liệu trả về DAO tuỳ chỉnh

Gói mới

Để ngăn chặn các vấn đề về khả năng tương thích với các hoạt động triển khai Room 2.x hiện có và đối với các thư viện có phần phụ thuộc bắc cầu vào Room (ví dụ: WorkManager), Room 3.0 nằm trong một gói mới, tức là gói này cũng có một nhóm maven và mã nhận dạng cấu phần phần mềm mới. Ví dụ: androidx.room:room-runtime đã trở thành androidx.room3:room3-runtime và các lớp như androidx.room.RoomDatabase hiện sẽ nằm tại androidx.room3.RoomDatabase.

Không có API SupportSQLite

Room 3.0 được hỗ trợ hoàn toàn bởi API SQLiteDriver và không còn tham chiếu đến các loại SupportSQLite như SupportSQLiteDatabase hoặc các loại Android như Cursor nữa. Đây là thay đổi quan trọng nhất giữa Room 3.0 và 2.x kể từ khi các API RoomDatabase phản ánh SupportSQLiteDatabase cùng với API để nhận SupportSQLiteOpenHelper đã bị xoá. Giờ đây, bạn bắt buộc phải có SQLiteDriver để tạo RoomDatabase.

Ví dụ: các API cho hoạt động trực tiếp trên cơ sở dữ liệu được thay thế bằng các API tương đương của trình điều khiển:

// Room 2.x
roomDatabase.runInTransaction { ... }

// Room 3.x
roomDatabase.withWriteTransaction { ... }
// Room 2.x
roomDatabase.query("SELECT * FROM Song").use { cursor -> ... }

// Room 3.x
roomDatabase.useReaderConnection { connection ->
  connection.usePrepared("SELECT * FROM Song") { stmt -> ... }
}

Các API gọi lại có SupportSQLiteDatabase làm đối số cũng đã được thay thế bằng API tương đương có SQLiteConnection làm đối số. Đây là các hàm gọi lại di chuyển, chẳng hạn như Migration.onMigrate()AutoMigrationSpec.onPostMigrate() cùng với các hàm gọi lại cơ sở dữ liệu, chẳng hạn như RoomDatabase.Callback.onCreate(), RoomDatabase.Callback.onOpen(), v.v.

Nếu Room đang được dùng trong một dự án KMP, thì việc di chuyển sang phiên bản 3.0 sẽ đơn giản hơn vì chủ yếu chỉ liên quan đến việc cập nhật các tham chiếu nhập. Nếu không, bạn có thể áp dụng cùng một chiến lược di chuyển từ Room chỉ dành cho Android sang KMP. Hãy xem Hướng dẫn di chuyển Room KMP.

Trình bao bọc SupportSQLite

Room 3.x giữ lại trình bao bọc SupportSQLite được tạo trong phiên bản 2.x để giúp việc di chuyển trở nên dễ dàng hơn và hiện nằm trong một cấu phần phần mềm mới androidx.room3:room3-sqlite-wrapper. API tương thích cho phép bạn chuyển đổi một RoomDatabase thành SupportSQLiteDatabase. Bạn có thể thay thế các lệnh gọi roomDatabase.openHelper.writableDatabase bằng roomDatabase.getSupportWrapper().

Ưu tiên Kotlin và Coroutine

Để phát triển thư viện tốt hơn, Room 3.0 chỉ tạo mã Kotlin và chỉ là một Trình xử lý ký hiệu Kotlin (KSP). So với Room 2.x, không có quá trình tạo mã Java và không thể định cấu hình trình xử lý chú giải thông qua KAPT hoặc JavaAP trong Room 3.0. Xin lưu ý rằng KSP có thể xử lý các nguồn Java và trình biên dịch Room sẽ tạo mã cho cơ sở dữ liệu, các thực thể hoặc DAO có khai báo nguồn bằng Java. Bạn nên có một dự án có nhiều mô-đun, trong đó việc sử dụng Room được tập trung và Trình bổ trợ Kotlin cho Gradle cũng như KSP có thể được áp dụng mà không ảnh hưởng đến phần còn lại của cơ sở mã.

Room 3.0 cũng yêu cầu sử dụng Coroutine và cụ thể hơn là các hàm DAO phải tạm ngưng trừ phi chúng trả về một loại phản ứng, chẳng hạn như Flow hoặc một loại kiểu dữ liệu trả về DAO tuỳ chỉnh. Các API Room để thực hiện các thao tác cơ sở dữ liệu cũng là các hàm tạm ngưng, chẳng hạn như RoomDatabase.useReaderConnectionRoomDatabase.useWriterConnection.

Không giống như Room 2.x, bạn không thể định cấu hình RoomDatabase bằng Executor nữa. Thay vào đó, bạn có thể cung cấp CoroutineContext cùng với một trình điều phối thông qua trình tạo cơ sở dữ liệu.

API InvalidationTracker trong Room 3.0 dựa trên Flow, InvalidationTracker.Observer sẽ bị xoá cùng với các API liên quan addObserverremoveObserver. Cơ chế phản ứng với thao tác cơ sở dữ liệu là thông qua Coroutine Flow. Bạn có thể tạo Coroutine Flow thông qua API createFlow() trong InvalidationTracker.

Ví dụ về cách sử dụng:

fun getArtistTours(from: Date, to: Date): Flow<Map<Artist, TourState>> {
    return db.invalidationTracker.createFlow("Artist").map { _ ->
        val artists = artistsDao.getAllArtists()
        val tours = tourService.fetchStates(artists.map { it.id })
        associateTours(artists, tours, from, to)
    }
}

Hỗ trợ trên web

Bản phát hành Room 3.0 bổ sung JavaScript và WasmJs làm mục tiêu KMP. Kết hợp với việc phát hành các giao diện SQLiteDriver (androidx.sqlite:sqlite) cũng nhắm đến JavaScript và WasmJs, cùng với trình điều khiển WebWorkerSQLiteDriver mới nằm trong cấu phần phần mềm androidx.sqlite:sqlite-web mới, bạn có thể sử dụng Room trong mã chung nhắm đến tất cả các nền tảng KMP chính.

Do bản chất không đồng bộ của các nền tảng web, nên các Room API lấy SQLiteStatement làm đối số hiện là các hàm tạm ngưng. Ví dụ về các hàm này là Migration.onMigrate(), RoomDatabase.Callback.onCreate(), PooledConnection.usePrepared() và các hàm khác. Trong các API trình điều khiển, API không đồng bộ thường có trên tất cả các nền tảng và API đồng bộ thường có cho các mục tiêu không phải là web. Do đó, một dự án không nhắm đến web có thể tiếp tục sử dụng các API đồng bộ (SQLiteDriver.open(), SQLiteConnection.prepare()SQLiteStatement.step()) trong mã chung. Trong khi đó, một dự án chỉ nhắm đến web phải sử dụng các API không đồng bộ (SQLiteDriver.openAsync(), SQLiteConnection.prepareAsync()SQLiteStatement.stepAsync()).

Để thuận tiện, gói androidx.sqlite cũng đã thêm các hàm tiện ích tạm ngưng có tên đồng bộ của các API được đề cập (ngoài SQLiteConnection.executeSQL), bạn nên dùng các API này khi dự án nhắm đến cả nền tảng web và không phải web vì các API này là các khai báo dự kiến / thực tế sẽ gọi đúng biến thể dựa trên các nền tảng. Đây là các API mà thời gian chạy của Room sử dụng và cho phép sử dụng trình điều khiển trong mã chung cho tất cả các nền tảng được hỗ trợ.

Ví dụ về cách sử dụng:

import androidx.sqlite.executeSQL
import androidx.sqlite.step

roomDatabase.useWriterConnection { connection ->
    val deletedSongs = connection.usePrepared(
        "SELECT count(*) FROM Song"
    ) { stmt ->
        stmt.step()
        stmt.getLong(0)
    }
    connection.executeSQL("DELETE FROM Song")
    deletedSongs
}

WebWorkerSQLiteDriver là một cách triển khai SQLiteDriver giao tiếp với một Web Worker để thực hiện thao tác cơ sở dữ liệu ngoài luồng chính và cho phép lưu trữ cơ sở dữ liệu trong Origin Private File System (OPFS). Để khởi tạo trình điều khiển, bạn cần có một worker triển khai giao thức giao tiếp đơn giản. Giao thức này được mô tả trong WebWorkerSQLiteDriver KDoc.

Hiện tại, WebWorkerSQLiteDriver không đi kèm với một worker mặc định triển khai giao thức giao tiếp, nhưng ví dụ: cơ sở mã androidx chứa một worker triển khai có thể được dùng trong dự án của bạn. Nó sử dụng WASM của SQLite và lưu trữ cơ sở dữ liệu trong OPFS. Worker mẫu được xuất bản dưới dạng một gói NPM cục bộ và nhờ khả năng hỗ trợ các phần phụ thuộc NPM của Kotlin, bạn có thể tạo một mô-đun KMP nhỏ để phân phát worker.

Hãy xem dự án GitHub sau đây minh hoạ cách sử dụng web worker cục bộ cho Room.

Sau khi bạn thiết lập một worker trong dự án, việc định cấu hình Room cho Web cũng tương tự như các nền tảng khác:

fun createDatabase(): MusicDatabase {
    return Room.databaseBuilder<MusicDatabase>("music.db")
        .setDriver(WebWorkerSQLiteDriver(createWorker()))
        .build()
}

fun createWorker() =
    Worker(js("""new URL("sqlite-web-worker/worker.js", import.meta.url)"""))

Phiên bản trình điều khiển Web trong tương lai có thể chứa một worker mặc định được xuất bản trong NPM, giúp việc thiết lập web trở nên đơn giản hơn.

Loại dữ liệu trả về DAO tuỳ chỉnh

Nhiều hoạt động tích hợp kiểu dữ liệu trả về DAO (chẳng hạn như hoạt động tích hợp cho RxJava và Paging) đã được chuyển đổi để sử dụng một API mới trong Room 3.0 có tên là trình chuyển đổi kiểu dữ liệu trả về DAO. Hàm chuyển đổi kiểu dữ liệu trả về DAO (@DaoReturnTypeConverter) cho phép chuyển đổi kết quả của một hàm DAO thành một kiểu tuỳ chỉnh do hàm được chú thích xác định. Các hàm này cho phép tham gia vào mã do Room tạo, mã này sẽ chuyển đổi kết quả truy vấn thành các đối tượng dữ liệu. Các lớp chứa trình chuyển đổi kiểu dữ liệu trả về DAO phải được đăng ký thông qua chú giải @DaoReturnTypeConverters trong các khai báo @Database hoặc @Dao.

Ví dụ: để truy vấn DAO trả về PagingSource, giờ đây, bạn phải đăng ký lớp trình chuyển đổi nằm trong androidx.room3:room3-paging:

@Dao
@DaoReturnTypeConverters(PagingSourceDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song)
    fun getSongsPaginated(): PagingSource<Int, Song>
}

Các hoạt động tích hợp hiện có đã được chuyển sang trình chuyển đổi kiểu dữ liệu trả về DAO:

Kiểu dữ liệu trả về Lớp trình chuyển đổi Cấu phần phần mềm
PagingSource PagingSourceDaoReturnTypeConverter androidx.room3:room3-paging
Observable, Flowable, Completable, Single, Maybe RxDaoReturnTypeConverters androidx.room3:room3-rxjava3
ListenableFuture GuavaDaoReturnTypeConverter androidx.room3:room3-guava
LiveData LiveDataDaoReturnTypeConverter androidx.room3:room3-livedata

Giống như trình chuyển đổi loại cột, trình chuyển đổi kiểu dữ liệu trả về DAO có thể được ứng dụng xác định. Ví dụ: một ứng dụng có thể khai báo @DaoReturnTypeConverter cho loại web kotlin.js.Promise.

object PromiseDaoReturnTypeConverter {
    @DaoReturnTypeConverter([OperationType.READ, OperationType.WRITE])
    fun <T> convert(
        db: RoomDatabase,
        executeAndConvert: suspend () -> T
    ): Promise<T> {
        return db.getCoroutineScope().promise { executeAndConvert() }
    }
}

Sau đó, bộ chuyển đổi ở trên cho phép các hàm truy vấn DAO trả về Promise:

@Dao
@DaoReturnTypeConverters(PromiseDaoReturnTypeConverter::class)
interface MusicDao {
    @Query("SELECT * FROM Song")
    fun getAllSongs(): Promise<List<Song>>
}

Hàm @DaoReturnTypeConverter có một số yêu cầu về số lượng tham số mà hàm phải có và các loại tham số. Các tham số có thể là:

  • db: RoomDatabase: (Không bắt buộc) Cung cấp quyền truy cập vào thực thể RoomDatabase. Điều này có thể hữu ích khi thực hiện các thao tác bổ sung với cơ sở dữ liệu hoặc truy cập vào phạm vi coroutine.
  • tableNames: Array<String>: (Không bắt buộc) Chứa các bảng được truy cập của truy vấn, hữu ích cho việc hỗ trợ các loại có thể quan sát / phản ứng khi kết hợp với API InvalidationTracker.createFlow() của Room.
  • rawQuery: RoomRawQuery: (Không bắt buộc) Chứa một phiên bản của truy vấn tại thời gian chạy, cho phép các quy tắc chuyển đổi như chiến lược LIMIT / OFFSET do PagingSourceDaoReturnTypeConverter triển khai.
  • executeAndConvert: suspend () -> T: (Bắt buộc) Hàm do Room tạo sẽ thực thi truy vấn và phân tích cú pháp kết quả của truy vấn đó thành các đối tượng dữ liệu.

Để biết thêm thông tin về các yêu cầu để tạo trình chuyển đổi kiểu dữ liệu trả về DAO, hãy xem KDoc trên API @DaoReturnTypeConverter.