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 25 tháng 3 năm 2026 - - - 3.0.0-alpha02

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 tuỳ 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 đồ được tạo (là kết quả của các tác vụ biên dịch và được dùng để tự động di chuyển) được định cấu hình đúng cách để 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ợ, 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 phần mở rộng room3.

Groovy

plugins {
    id 'androidx.room3'
}

room3 {
    schemaDirectory "$projectDir/schemas"
}

Kotlin

plugins {
    id("androidx.room3")
}

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

Bạn phải thiết lập schemaDirectory khi sử dụng trình bổ trợ Room cho Gradle. Việ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 khác nhau cũng như phần phụ trợ của trình biên dịch (kotlinc, KSP) để xuất các tệp giản đồ vào các thư mục có hương vị, ví dụ: schemas/flavorOneDebug/com.package.MyDatabase/1.json. Bạn nên kiểm tra các tệp này vào kho lưu trữ để dùng cho quá trình xác thực và tự động di chuyển.

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ề Trình theo dõi sự cố để biết thêm thông tin.

Phiên bản 3.0

Phiên bản 3.0.0-alpha02

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

Phát hành androidx.room3:room3-*:3.0.0-alpha02. Phiên bản 3.0.0-alpha02 bao gồm các thay đổi sau.

Tính năng mới

  • Hỗ trợ FTS5: Thêm tính năng hỗ trợ FTS5 vào Room thông qua chú giải @Fts5. Tính năng này bao gồm các hằng số mới cho bộ phân tích mã thông báo FTS5 (TOKENIZER_ASCIITOKENIZER_TRIGRAM) và một enum cho tuỳ chọn FTS "detail" (FULL, COLUMN, và NONE). (I90934, b/146824830)
  • Mục tiêu phân trang Room: Thêm các mục tiêu js, wasmJs, tvOSwatchOS vào room3-paging. (Icffd3, b/432783733)

Thay đổi về API

  • Đa nền tảng clearAllTables(): Chuẩn hoá clearAllTables(), giúp tính năng này có sẵn trên tất cả các nền tảng. Tính năng này cũng đã được chuyển đổi thành hàm suspend. (I434ae, b/322846465)
  • Di chuyển mang tính phá huỷ: Thêm giá trị tham số mặc định vào dropAllTables trong các API fallbackToDestructiveMigration. (Ica88b, b/438041176)
  • Thay đổi về API thử nghiệm:

    1. Di chuyển @ExperimentalRoomApi sang room-common để cho phép đánh dấu các API dựa trên chú giải là thử nghiệm.

    2. Thêm RoomWarning thử nghiệm để ngăn chặn yêu cầu về @ConstructedBy trong phần khai báo cơ sở dữ liệu Room. Trong trường hợp này, DatabaseConstructor sẽ không được tạo và bạn phải triển khai nhà máy thông qua DatabaseBuilder. (If5443)

Sửa lỗi

  • Nguồn phân trang: Cập nhật PagingSourceDaoReturnTypeConverter để cho biết chính xác rằng hàm chuyển đổi của hàm này dành cho các truy vấn READ. (I3b067, b/139872302)

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à 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ú giải cốt lõi được 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ú giải bằng @Database là điểm truy cập cho trình xử lý chú giải của Room.
  • Phần 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ú giải bằng @Entity.
  • Các thao tác với cơ sở dữ liệu được xác định trong các phần 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ú giải @Query.
  • Trong thời gian chạy, bạn có thể lấy được quá trình triển khai cơ sở dữ liệu thông qua RoomDatabase.Builder 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.

Sau đây là những điểm khác biệt chính mang tính phá huỷ giữa Room 2.x:

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

Cùng với những thay đổi mang tính phá huỷ, Room 3.0 mang đến chức năng mới so với 2.x:

  • Hỗ trợ JS và WasmJS
  • Kiểu 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 cách triển khai Room 2.x hiện có và cho 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. Điều này có nghĩa là gói này cũng có một nhóm maven và mã 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ợ đầy đủ bởi các 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. Đâ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 để lấy SupportSQLiteOpenHelper đã bị xoá. Giờ đây, bạn phảiSQLiteDriver để tạo RoomDatabase.

Ví dụ: các API cho các thao tác trực tiếp với 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 như Migration.onMigrate()AutoMigrationSpec.onPostMigrate() cùng với các lệnh gọi lại cơ sở dữ liệu như RoomDatabase.Callback.onCreate(), RoomDatabase.Callback.onOpen(), v.v.

Nếu bạn đang sử dụng Room trong một dự án KMP, thì việc di chuyển sang 3.0 sẽ đơn giản hơn vì chủ yếu là cập nhật các tham chiếu nhập. Nếu không, chiến lược di chuyển tương tự từ Room trong Android (chỉ dành cho Android) sang KMP sẽ được áp dụng. 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 2.x để giúp việc di chuyể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 RoomDatabase thành SupportSQLiteDatabase. Bạn có thể thay thế các lệnh gọi của 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 Kotlin Symbol Processor (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, thực thể hoặc DAO có phần khai báo nguồn ở Java. Bạn nên có một dự án nhiều mô-đun, trong đó việc sử dụng Room được tập trung và có thể áp dụng trình bổ trợ Kotlin cho Gradle và KSP 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 kiểu dữ liệu trả về DAO tuỳ chỉnh. Các API Room để thực hiện các thao tác với 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 còn có thể định cấu hình RoomDatabase bằng Executor. 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ủa cơ sở dữ liệu.

Các API InvalidationTracker trong Room 3.0 dựa trên Flow, InvalidationTracker.Observer 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 có thể được tạo 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ợ web

Bản phát hành Room 3.0 thêm JavaScript và WasmJs làm mục tiêu KMP. Kết hợp với bản phát hành các giao diện SQLiteDriver (androidx.sqlite:sqlite) cũng nhắm đến JavaScript và WasmJs và một trình điều khiển mới WebWorkerSQLiteDriver nằm trong cấu phần phần mềm mới androidx.sqlite:sqlite-web, 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, các API Room 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, các API không đồng bộ là phổ biến trên tất cả các nền tảng và các API đồng bộ là phổ biến 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 mở rộng tạm ngưng có tên đồng bộ của các API được đề cập (với việc bổ sung SQLiteConnection.executeSQL). Bạn nên sử dụng các API này khi dự án nhắm đến cả nền tảng web và không phải là web vì các API là các phần khai báo dự kiến / thực tế sẽ gọi biến thể phù hợp 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 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 Hệ thống tệp riêng tư của nguồn gốc (OPFS). Để tạo thực thể cho trình điều khiển bạn cần có một trình thực thi 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 trình thực thi mặc định triển khai giao thức giao tiếp, nhưng ví dụ: cơ sở mã androidx chứa một trình thực thi cách triển khai có thể được sử dụng trong dự án của bạn. Trình thực thi này sử dụng WASM của SQLite và lưu trữ cơ sở dữ liệu trong OPFS. Trình thực thi ví dụ được phát hành dưới dạng gói NPM cục bộ và nhờ khả năng hỗ trợ của Kotlin cho các phần phụ thuộc NPM, bạn có thể tạo một mô-đun KMP nhỏ để phục vụ trình thực thi.

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

Sau khi thiết lập trình thực thi 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 trình thực thi mặc định được phát hành trong NPM, giúp việc thiết lập web trở nên đơn giản hơn.

Kiểu dữ liệu trả về DAO tuỳ chỉnh

Nhiều cách tích hợp kiểu dữ liệu trả về DAO, chẳng hạn như các cách tích hợp cho RxJava và Phân trang, đã đượ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 hàm DAO thành một kiểu tuỳ chỉnh do hàm được chú giải xác định. Các hàm này cho phép tham gia vào mã được tạo của Room để 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 @DaoReturnTypeConverters chú giải trong phần khai báo @Database hoặc @Dao.

Ví dụ: để truy vấn DAO trả về PagingSource, bạn phải đăng ký lớp 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 cách 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 chuyển đổi Cấu phần phần mềm
PagingSource PagingSourceDaoReturnTypeConverter androidx.room3:room3-paging
Có thể quan sát được, 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 kiểu cột, trình chuyển đổi kiểu dữ liệu trả về DAO có thể được xác định bởi ứng dụng. Ví dụ: một ứng dụng có thể khai báo @DaoReturnTypeConverter cho kiểu 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 đó, trình 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 này phải có và các kiểu của 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 RoomDatabase thực thể, có thể hữu ích cho việc 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 kiểu có thể quan sát được / 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 thực thể của truy vấn trong thời gian chạy, cho phép các phép biến đổi như chiến lược LIMIT / OFFSET do PagingSourceDaoReturnTypeConverter triển khai.
  • executeAndConvert: suspend () -> T: (Bắt buộc) Hàm được tạo của Room 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ữ về trả về DAO, hãy xem KDoc trên @DaoReturnTypeConverter API.