Android SQLite Room

James Lin
5 min readJul 11, 2018

--

首先先在 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 觀看的結果:

--

--

James Lin
James Lin

No responses yet