1. Introduction
Since Google launched Room, we can use SQLite database gracefully. Of course, with the combination of Room+Paging, the code is written and flies. Please refer to the tutorial below for details on how to use Room+Paging. Paging in Android: juejin.cn/post/684490…
Add a reference to the Room library in your App’s build.gradle file.
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
implementation "androidx.room:room-testing:$room_version"
implementation "androidx.room:room-ktx:$room_version"
Copy the code
2. Create the Entity
First we will create a Data class as the Entity class of the database. Then add additional information about the database using the annotations described below.
@Entity
Add an @Entity annotation to the entity you want to create.
@Entity(tableName = "users_table")
data class User(...)
Copy the code
You can also add as many parameters after @Entity as you want.
tableName
, you can name the Table. The sample,tableName = "users_table"
.primaryKeys
, you can specify a primary key for Table. The sample,primaryKeys = {"firstName", "lastName"}
.Index
In order to speed up the data query speed, you can add indexes. The sample,indices = {@Index("lastName")
.unique
Can be added when the index needs to ensure the uniqueness of information in two columns. The sampleindices = {@Index(value = {"first_name", "last_name"},unique = true)}
@PrimaryKey
The @primaryKey annotation has the same effect as primaryKeys in @Entity above. You can also add autoGenerate=true for auto-added primary keys.
@PrimaryKey(autoGenerate = true)
val id: Int? = null.Copy the code
@ColumnInfo
Add the list name name=”name” for the attributes in the entity.
@ColumnInfo(name = "birthday")
val birthday: String
Copy the code
@Ignore
If you have attributes in your Entity that you do not want to store in the database, you can add the @ignore annotation.
@Ignore
val nationality: String
Copy the code
@Embedded
If there are other objects in the Entity class, you can use @Embedded to nest them. Of course the object to be nested also needs to be an Entity class annotated by @Entity.
@Embedded
val address: Address
Copy the code
3. Create a Dao
@Dao
The full name of Dao is Data Access Object, is a Data Access Object is an object-oriented database interface. In general development, a Dao needs to be abstracted separately. Create an interface in Room and add the @DAO annotation.
@Dao
interface UserDao {}
Copy the code
@Query
You need to add @Query to the method that implements the Query, along with the SQL statement to be queried.
@Query("SELECT * FROM users_table where first_name = :firstName")
suspend fun getUserByFirstName(firstName:String): List<User>
Copy the code
If a method has parameters passed in that need to be used in an SQL query, you can use :parameter to bind the parameters.
@Insert
To Insert data into a database, you need to annotate @INSERT, but you don’t need to add SQL statements. You need to pass in an object inserted into the database as a parameter to the function.
@Insert
suspend fun insertUser(users: List<User>)
Copy the code
@Delete
To Delete data from the database, you need to annotate @delete, but you do not need to add SQL statements. You need to pass the deleted object as an argument to the function.
@Delete
suspend fun deleteUser(users: List<User>)
Copy the code
@Update
The @update annotation is required to Update data in the database, but no SQL statement is required. You need to pass the updated object as an argument to the function.
@Update
public void updateUsers(User... user);
Copy the code
@Transaction
SQLite transactions can be added using the @Transaction annotation.
@Transaction
suspend fun deleteAllAndInsertUser(users: List<User>) {
deleteUser(getAll())
insertUser(users)
}
Copy the code
The overall code
@Dao
interface UserDao {
@Query("SELECT * FROM users_table")
suspend fun getAll(a): List<User>
@Insert
suspend fun insertUser(user: User)
@Update
public void updateUsers(User... user);
@Delete
suspend fun deleteUser(users: List<User>)
@Transaction
suspend fun deleteAllAndInsertUser(users: List<User>) {
deleteUser(getAll())
users.forEach { insertUser(it) }
}
}
Copy the code
4. Create RoomDatabase
Example code is as follows:
@Database(version = 1, entities = [User::class]) // Add a Database annotation. You also need to add version information and entities information
@TypeConverters(Converter::class) // Add TypeConverter annotations
abstract class AppDatabase : RoomDatabase() {
companion object {
private const val DB_NAME = "user_database.db"
private var INSTANCE: AppDatabase? = null
private var lock = Any()
fun getInstance(context: Context): AppDatabase {
synchronized(lock) {
if (INSTANCE == null) {
// The first argument is Context, the second argument is DB class, and the third argument is DB name
INSTANCE =
Room.databaseBuilder(context, AppDatabase::class.java.DB_NAME).build()}returnINSTANCE!! }}fun destroyInstance(a) {
INSTANCE = null}}abstract fun getUserDao(a): UserDao
}
Copy the code
The database class needs to inherit from RoomDatabase, and it must declare an abstract class. It is also important to note that creating an instance of a database is very performance critical and cannot be repeated. A common approach to this problem is to design the instance creation method into the Singleton pattern.
@Database
You need to annotate the Database class with @database. The following information is also not required.
version
To specify the version of the database.entities
, all entity classes need to be specified.
@Database(version = 1, entities = [User::class])
Copy the code
@TypeConverter
Room is a basic data type that supports strings, integers, etc., but when we encounter other data types, we need to use @typeconverter to convert data types. For example, when the birthday attribute of User is Date, the data type conversion is required.
class Converter {
@TypeConverter
fun longToDate(timeStamp: Long?).: Date? {
if (timeStamp == null) return null
return Date(timeStamp)
}
@TypeConverter
fun dateToLong(date: Date?).: Long? {
if (date == null) return null
return date.time
}
}
Copy the code
5. Database upgrade and Migration
When the App has been published and needs to update and change the database structure, it needs to use the data migration of the database. Room provides us with the function of database upgrade.
Upgrade from version 1 to version 2
val MIGRATION_1_2 = object : Migration(1.2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
"PRIMARY KEY(`id`))")}}// Upgrade from version 2 to version 3
val MIGRATION_2_3 = object : Migration(2.3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE Book ADD COLUMN pub_year INTEGER")}}// Add the version upgrade to Room builder
Room.databaseBuilder(applicationContext, MyDb::class.java."database-name")
.addMigrations(MIGRATION_1_2, MIGRATION_2_3).build()
Copy the code
6. Github
Making: github.com/HyejeanMOON…
Property Animation for Android: juejin.cn/post/684490… Android ConstraintLayout: juejin.cn/post/684490… In RecyclerView can cope with multiple ViewType libraries -Groupie: juejin.cn/post/684490… Use of Google MergeAdapter: juejin.cn/post/684490… Paging in Android: juejin.cn/post/684490… Android UI testing Espresso: juejin.cn/post/684490… Android WorkManager: juejin.cn/post/684490…