首先先在 Gradle 加上
dependencies{
...implementation "android.arch.persistence.room:runtime:1.0.0"kapt "android.arch.persistence.room:compiler:1.0.0"testImplementation "android.arch.persistence.room:testing:1.0.0"
...
}
Kotlin 的 Poject 需要使用 kapt!!!
沒有加上這行:kapt “android.arch.persistence.room:compiler:1.0.0”
會造成 Can't find impletation class 啥的....
注意:使用Kapt需要在Gradle上加上這一行
apply plugin: 'kotlin-kapt'
接著看看Data Class
@Entity(tableName = TableName)
class User {
@PrimaryKey(autoGenerate = true)
var uid: Int = 0
@ColumnInfo
var name: String? = null
@ColumnInfo
var birthDay: String? = null
companion object {
const val TableName = "TABLE_USER"
}
}
Entity:代表這一個class是在資料庫裡面的一個"實體"。
PrimaryKey:宣告下面的屬性是Primarykey,如果 autoGenerate是True的話,屬性要設置 Int 的型態。
ColumnInfo:可以命名資料庫的欄位,此範例沒有命名,它會使用Class中"屬性"的名字去當作資料庫中"欄位"的名字。
使用方式:
@ColumnInfo(name = “userName”)
接著設置 Dao 的 Interface,看到好處了八~
在之前的SQLiteOpenHelper需要寫許多的資料庫指令,串字串阿,之類的。
現在只要用一個 Interface 就解決了這個問題,我們不需要去實作這個 Interface ,只需要在上面加上 @ Query(...) , @ Insert(…) , @ delete(…) ,
@ update(…)
@Dao
interface UserDao {
@Query("select * from " + User.TableName)
fun allUser(): List<User>
@Query("select * from " + User.TableName + " Where uid= :uid")
fun getUser(uid: Int): User
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(user: User)
}
接著看到 Database ,它是一個abstract class,它會回傳 Dao,讓需要存取資料庫的物件可以拿到 Dao 去存取資料庫,官網建議這個 class 應該要使用 Singleton。
注意:.allowMainThreadQueries(),這個方法讓 getDatabase()可以在MainThread上執行,不建議這樣做,比較建議的做法是在另一個 Thread 執行 Query 等動作。
@Database(entities = arrayOf(User::class), version = 1)
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
const val DBNAME = "User"
@Volatile
private var INSTANCE: UserDatabase? = null
fun getDatabase(context: Context): UserDatabase? {
if (INSTANCE == null) {
synchronized(UserDatabase::class.java) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder<UserDatabase>(context,
UserDatabase::class.java,
DBNAME)
.allowMainThreadQueries()
.build()
}
}
}
return INSTANCE
}
fun destoryInstance() {
if (INSTANCE != null) {
INSTANCE!!.close()
}
INSTANCE = null
}
}
}
使用 Stetho 觀看的結果: