Android 数据库框架Room的简单使用

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u012149399/article/details/79391369

 

官方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<User>

    @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<PersonInfo>? = 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<PersonInfo>? = null)

注:用@Embedded保留AlertInfo,用@Relation实现关联表的查询

 

Dao类:

注:获取数据时使用中间类,保存数据时分别进行保存。PersonInfo类中的数据,alertId字段值为AlertInfo中的id字段值。

@Dao
interface AlertDao {
    @Query("select * from alerts")
    fun getAlerts(): List<AlertPersonInfo>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(alert: List<AlertInfo>)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertPerson(persons: List<PersonInfo>)
}

如何使用?

private fun test() {
        val list = ArrayList<AlertInfo>()
        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, R> T.exec(block: T.() -> R, rtn: (R) -> Unit): T {
    Observable.create<R> { 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("更新成功")
})

 

展开阅读全文

没有更多推荐了,返回首页