The Room persistence library provides an abstraction layer on top of SQLite to allow fluent database access while taking full advantage of the power of SQLite. Specifically, Room has the following advantages:
- Compile-time validation for SQL queries.
- Handy annotations that minimize repetitive and error-prone boilerplate code.
- Simplified database migration path.
step1: app/build.gradle
Introduce room in
implementation "androidx.room:room-ktx:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
step2: create entity class
This class is the data structure to be stored, by @Entity(tableName="test_table")
defining and specifying the table name. Each attribute in the class represents a column in the table . Room will eventually use these properties to create the table and instantiate the object in the database row
//声明数据表,并且指定数据表名称
@Entity(tableName = "test_table")
data class TestEntity(@PrimaryKey(autoGenerate = true) val id: Int, @ColumnInfo(name = "name")val name:String)
//如果列名也叫做word可以省略@ColumnInfo
step3: create DAO
In fact, it is to provide addition, deletion, modification and query to the data table. In DAO (Data Access Objects), you can specify an SQL query and associate it with a method call. @Insert
The compiler examines the SQL and generates queries based on convenient annotations such as . Room uses DAOs to create a clean API for your code. DAO must be an interface or abstract class. By default, all queries must be executed on separate threads. Room supports Kotlin coroutines , you can annotate queries with suspend
the decorator and call them from coroutines or other suspending functions.
@Dao
interface TestDao {
@Query("SELECT * FROM test_table ORDER BY word ASC")
fun getSavedEntities(): Flow<List<TestEntity>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(entity: TestEntity)
@Query("DELETE FROM test_table")
suspend fun deleteAll()
}
- TestDao is an interface, and DAO must be an interface or an abstract class .
@Dao
The annotation identifies it as the DAO class of Room.suspend fun insert(word: TestEntity)
: Declare the pending function to insert a word.@Insert
Annotation is a special kind of DAO method annotation, when using DAO method annotation, you don't need to provide any SQL! (also and annotations for deleting@Delete
and@Update
)onConflict = OnConflictStrategy.IGNORE
: The selected onConflict strategy ignores new words that are identical to existing words in the list. See the documentation for details on the available conflict strategies .suspend fun deleteAll()
: Declare a suspending function to delete all words.- There is no annotation to facilitate deletion of multiple entities, so entities should have generic
@Query
annotations . @Query
("DELETE FROM word_table"):@Query
Requires you to provide a SQL query as a string parameter to the annotation to perform complex read queries and other operations.- fun getSavedEntities(): Use Flow to encapsulate the returned List. Flow is an asynchronous sequence of values. Flow generates values one at a time (rather than all values at once) through asynchronous operations such as network requests, database calls, or other asynchronous code. Its API supports coroutines, so coroutines can also be used to complete Flow.
- @Query("SELECT * test_table ORDER BY word ASC"): A query that returns a list of words sorted in ascending order.
step4: Realize the room database.
Room database class must be abstract and must extend RoomDatabase. Typically only one Room database instance is required for the entire application.
@Database(entities = arrayOf(TestEntity::class), version = 1, exportSchema = false)
public abstract class TestRoomDatabase : RoomDatabase() {
abstract fun wordDao(): TestDao
companion object {
@Volatile
private var INSTANCE: TestRoomDatabase? = null
fun getDatabase(context: Context): TestRoomDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
TestRoomDatabase::class.java,
"test_database"
).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
- Room database classes must be abstract and extend
RoomDatabase
. - You can annotate
@Database
this class as a Room database, and use the annotation parameters to declare the entities in the database and set the version number. Each entity corresponds to a table that will be created in the database. Database migrations are not covered here, so exportSchema has been set to false to avoid build warnings. In a real application, consider setting up a directory for Room to export the schema to check the current schema into the version control system. - The database exposes the DAOs through each @Dao's abstract "getter" method.
- A singleton TestRoomDatabase is defined to prevent multiple instances of the database from being opened at the same time.
- getDatabase will return the singleton. On first use, it creates the database by using Room's database builder to create a RoomDatabase object in the application context of the TestRoomDatabase class and name it "word_database".
step5: Use DAO in Repository
class TestRepository(private val testDao: TestDao) {
val allEntities: Flow<List<TestEntity>> = testDao.getSavedEntities()
@WorkerThread
suspend fun insert(entity: TestEntity) {
testDao.insert(entity)
}
}
step6: Use Repository in ViewModel
Hilt is used here. First query all the results in the viewModel, convert the flow into liveData, and register the listener in the required activity. When the database data changes, the listener can receive the corresponding change data, such as after calling insert
@HiltViewModel
class TestViewModel @Inject constructor(private val repository: TestRepository) :ViewModel() {
val allWords: LiveData<List<Word>> = repository.allEntities.asLiveData()
fun insert(entity: TestEntity) = viewModelScope.launch {
repository.insert(entity)
}
}
The above is the simple use of Room.
at last
If you want to become an architect or want to break through the 20-30K salary range, then don't be limited to coding and business, but you must be able to select models, expand, and improve programming thinking. In addition, a good career plan is also very important, and the habit of learning is very important, but the most important thing is to be able to persevere. Any plan that cannot be implemented consistently is empty talk.
If you have no direction, here I would like to share with you a set of "Advanced Notes on the Eight Major Modules of Android" written by a senior architect of Ali, to help you organize the messy, scattered and fragmented knowledge systematically and efficiently. Master the various knowledge points of Android development.
Compared with the fragmented content we usually read, the knowledge points of this note are more systematic, easier to understand and remember, and are arranged strictly according to the knowledge system.
Full set of video materials:
1. Interview collection
2. Source code analysis collection
3. The collection of open source frameworks
welcomes everyone to support with one click and three links. If you need the information in the article, directly scan the CSDN official certification WeChat card at the end of the article to get it for free↓↓↓
PS: There is also a ChatGPT robot in the group, which can answer your work or technical questions