Room is introduced

  1. Room is an Object Mapping (OM) database that can be easily accessed from Android applications.
  2. Room abstracts SQLite by providing a convenient API to query the database and validate it at compile time. And you can use the full power of SQLite with the type safety provided by the Java SQL query generator.

The structure of the Room

  1. Database: The Database extends the Abstract class of RoomDatabase. An instance of it is available through Room. DatabaseBuilder or Room. InMemoryDatabaseBuilder.
  2. Entity: represents a table structure.
  3. Dao: The data access object is the main component of Room and is responsible for defining the methods to access the database.

Declare dependencies

Def room_version = "2.3.0" implementation "Androidx. room: room-Runtime :$room_version" annotationProcessor "androidx.room:room-compiler:$room_version"Copy the code

Configure compiler options

Configure the compiler interpretation

  1. “Room. SchemaLocation “:”$projectDir/schemas”.tostring (), which is used to configure and export json files from the database schema to the specified directory
  2. “Room. incremental”:”true”:Gradle incremental annotation processor
  3. “Room. expandProjection”:”true”: Configure room to rewrite the query so that its top star projection, when expanded, contains only columns defined in the DAO method return type.
// Configure the compiler code android {... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments += [ "room.schemaLocation":"$projectDir/schemas".toString(),  "room.incremental":"true", "room.expandProjection":"true"] } } } }Copy the code

Defining data tables

Create a book table

@Entity(tableName = "book")
class Book {
    @PrimaryKey(autoGenerate = true)
    var id: Int = 0

    @ColumnInfo(name = "bookname")
    var name: String? = ""

    constructor(bookname: String?) {
        this.name = bookname
    }
}
Copy the code

Table annotation interpretation

  1. If you want to set a tableName, add it after @entity (tableName = “book”) instead of using the class name by default
  2. Declare table PrimaryKey @primarykey (autoGenerate = true)
  3. Change the table property column name @columnInfo (name = “bookName “), the default class field name
    1. Define the Dao class
@Dao interface BookDao { @Insert fun addBook(book : Book) @Query("SELECT * FROM book") fun loadAll(): List<Book? >? @Query("select * from book where name = :name") fun queryName(name : String) :List<Book? >? @Delete fun delete(song: Book?) }Copy the code

If the return value type and the table name of the query are not the same as the return value type or the table name of the query, the program will fail to compile during compilation, which reduces the risk of the program at runtime

    1. Define the database and generate the data classes
@Database(entities = [Book::class], version = 1)
abstract class RoomDaoManager : RoomDatabase() {

    abstract fun BookDao(): BookDao

    companion object {

        private val DATABASE_NAME = "dev_db.db"

        private var databaseInstance: RoomDaoManager? = null

        @Synchronized
        open fun getInstance(): RoomDaoManager? {

            if (databaseInstance == null) {

                databaseInstance = Room

                    .databaseBuilder(

                        MyApplication.instance(),

                        RoomDaoManager::class.java,

                        DATABASE_NAME
                    )

                    .allowMainThreadQueries()

                    .build()
            }
            return databaseInstance
        }
     }
}
Copy the code

Database Upgrade

  1. addMigrations(Migration migrations…) : A migration can handle multiple versions
  2. Migration(int startVersion, int endVersion): Each Migration can move between two defined versions, the initial version and the target version,
  3. Execute the updated SQL in the overwritten Migrate method and add the same fields to the corresponding Entity class to ensure that the fields are the same
Room .databaseBuilder( MyApplication.instance(), RoomDaoManager::class.java, DATABASE_NAME ) .allowMainThreadQueries() .addMigrations(MIGRATION_1_2) .build() ###addMigrations(Migration migrations...) ##Migration: Each Migration can move between the two versions defined. Val MIGRATION_1_2 = object: Migration(1, 2) { override fun migrate(database: ExecSQL ("ALTER TABLE Book ADD COLUMN SN TEXT NOT NULL DEFAULT ")}}Copy the code

LiveData and Room work together

// Def lifecycle_version = "2.2.0" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"Copy the code
Livedata.query ("SELECT * FROM book where id = :id") fun queryLiveData(id: Int): Livedata < book? >? // Call the query method bookDao? .queryLiveData(1)? .observe(this, Observer { Log.i("book-query","${it? .name}") })Copy the code

Rxjava works with Room

// Def room_version = "2.3.0" // optional - Rxjava2 support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - RxJava3 support for Room implementation "androidx.room:room-rxjava3:$room_version"Copy the code
@query ("SELECT * FROM book where id = :id") fun queryFlowable(id: Int): Flowable< book? >?Copy the code

Room database annotations

@Entity

The return value The method name role
ForeignKey[] foreignKeys() A list of foreign key constraints for an entity
String tableName() Database table name, default is class name
Index[] indices() The index lists
boolean inheritSuperIndices() If set to true, any indexes defined in the parent class of the class will be moved to the current entity
String[] ignoredColumns() List of column names ignored
String[] primaryKeys() A list of primary key column names

@Dao

Note the name The parameter types role
@Query() String The query SQL
@Delete Class Delete a corresponding entity
@Insert Parameter 1. Parameter 2. OnConflict 1. Add a corresponding entity class. 2.

@Database

Note the name The parameter types role
AutoMigration[] autoMigrations() A list of automatic migrations that can be performed on this database
Class[]<? > entities() A list of entities contained in the database
boolean exportSchema() You can set the annotation handler parameter (room.schemalocation) to tell Room to export the database schema to a folder
int version() Database Version
Class[]<? > views() A list of database views contained in the database.

conclusion

Rather than hiding the details of SQLite, Room tries to query the database by providing a convenient API and validate those queries at compile time. This allows you to access the full functionality of SQLite while having the type safety provided by the Java SQL query generator