官方demo:链接
依赖及配置:
apply plugin: 'kotlin-kapt'
implementation "android.arch.persistence.room:runtime:1.0.0"
kapt "android.arch.persistence.room:compiler:1.0.0"
1.定义一个实体类,如User.kt
import android.arch.persistence.room.ColumnInfo
import android.arch.persistence.room.Entity
import android.arch.persistence.room.PrimaryKey
/**
* @author Created by qlang on 2018/2/27.
*/
@Entity(tableName = "user")//注解是一个实体对象,也就是一个表"user"。
data class User(@PrimaryKey @ColumnInfo(name = "id") var id: Int, @ColumnInfo(name = "name") var name: String)//
2.定义一个Dao,用于具体的增删改查方法等。如UserDao.kt
import android.arch.persistence.room.Dao
import android.arch.persistence.room.Insert
import android.arch.persistence.room.OnConflictStrategy
import android.arch.persistence.room.Query
/**
* @author Created by qlang on 2018/2/27.
*/
@Dao//注解这是Dao对象,框架编译的时候会编译成具体的实现类位于:app/build/generated/source/apt/debug
interface UserDao {
@Query("select * from user where id = :id")
fun getUser(id: Int): User
@Query("select * from user")
fun getUsers(): List
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUser(user: User)
@Query("delete from user")
fun deleteAllUsers()
}
3.创建和获取数据库,创建一个单例类,如UserDatabase.kt
import android.arch.persistence.room.Database
import android.arch.persistence.room.Room
import android.arch.persistence.room.RoomDatabase
import android.content.Context
/**
* @author Created by qlang on 2018/2/27.
*/
@Database(entities = arrayOf(User::class), version = 1)//注解这是一个数据库类,并指定包含的实体类(表),版本等
abstract class UserDatabase : RoomDatabase() {
abstract fun userDao(): UserDao//定义dao对象,多个时写法类似
companion object {
@Volatile private var INSTANCE: UserDatabase? = null
fun getInstance(context: Context): UserDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
}
/**
* 创建数据库,如需指定数据库的其他位置SD卡等,名称参数传入文件绝对路径即可。如/sdcard/xxx.db
*/
private fun buildDatabase(context: Context) =
Room.databaseBuilder(context.applicationContext, UserDatabase::class.java, "User.db").build()
}
}
使用:
fun Context.userDao() = UserDatabase.getInstance(this).userDao()//简单的扩展一下,可写在任意类、文件中。在任意位置调用
Thread {
userDao().insertUser(User(Random().nextInt(10), "hhh"))
Log.e("QL", userDao().getUsers().toString())
}.start()
2018.5------------->补充
两个实体类的关联关系
如,AlertInfo对象中有另外一个对象的数组:
AlertInfo类
@Entity(tableName = "alerts")
data class AlertInfo(@PrimaryKey(autoGenerate = true) var id: Long, @Ignore var personInfo: List? = null)
注:使用@Ignore进行忽略,用中间类进行关联(见下文)
PersonInfo类
@Entity(tableName = "person", foreignKeys = (arrayOf(ForeignKey(entity = AlertInfo::class, parentColumns = arrayOf("id"),
childColumns = arrayOf("alertId"), onDelete = ForeignKey.CASCADE))))
data class PersonInfo(@PrimaryKey(autoGenerate = true) var id: Long, var alertId: Long, var idNum: String? = "")
注:添加外键,AlertInfo的id字段与PersonInfo的alertId字段为外键关系,并使用ForeignKey.CASCADE约束增删改。
定义一个额外的类AlertPersonInfo,用于查询数据时使用
data class AlertPersonInfo(@Embedded var alert: AlertInfo? = null,
@Relation(parentColumn = "id", entityColumn = "alertId") var personInfo: List? = null)
注:用@Embedded保留AlertInfo,用@Relation实现关联表的查询
Dao类:
注:获取数据时使用中间类,保存数据时分别进行保存。PersonInfo类中的数据,alertId字段值为AlertInfo中的id字段值。
@Dao
interface AlertDao {
@Query("select * from alerts")
fun getAlerts(): List
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(alert: List)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertPerson(persons: List)
}
如何使用?
private fun test() {
val list = ArrayList()
for (i in 0..5) {
val id = System.currentTimeMillis()
val info = AlertInfo(id, personInfo = arrayListOf(PersonInfo(System.currentTimeMillis(), id)))
list.add(info)
}
Thread {
activity?.alertDao()?.insert(list)
list.forEach { al -> al.personInfo?.let { activity?.alertDao()?.insertPerson(it) } }
val alerts = activity?.alertDao()?.getAlerts()
alerts?.forEach {
val alert = it.alert
alert?.personInfo = it.personInfo
alert?.let { it1 -> list.add(it1) }
}
}.start()
}
结合RxJava
定义一个扩展函数
/**
* 使用RxJava异步执行任务,并返回相应的值
*
* @param block 要执行耗时的任务,此函数体在子线程中执行,注意对变量的操作
* @param rtn 任务中的返回值,UI线程
* @return
*/
fun T.exec(block: T.() -> R, rtn: (R) -> Unit): T {
Observable.create { it.onNext(block()) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { rtn(it) }
return this
}
使用扩展函数
DbManager.getInstance(context).exec({
/*执行耗时任务*/
alertDao().update(alert)
}, {
/*执行完成的回调*/
if(it>0)showToast("更新成功")
})