在kotlin中使用room(Room Persistence Library)和遇到的坑

下面進(jìn)入正題,如何在kotlin中使用room;大致與java還是一樣的,但是會(huì)有幾處坑會(huì)在文中說(shuō)道;在文尾會(huì)總結(jié)

  • 第一步一定要在app 目錄下的 builde.gradle加入下面這個(gè)插件
apply plugin: 'kotlin-kapt'

//使用生成文件
kapt {
    generateStubs = true
}

1.創(chuàng)建Entity

@Entity(tableName = "story")
@TypeConverters(Converters::class)
data class StoryEntity constructor(
        @PrimaryKey
        @SerializedName("id") var id: Int) {

    constructor() : this(0)

    @ColumnInfo(name = "images")
    @SerializedName("images") var images: Array<String>? = null

    @ColumnInfo(name = "title")
    @SerializedName("title") var title: String? = null

    @ColumnInfo(name = "date")
    var date: Long = 0

    @ColumnInfo(name = "read")
    var read: Int = 0

    @ColumnInfo(name = "like")
    var like: Int = 0

    @ColumnInfo(name = "collection")
    var collection: Int = 0

    /**
     * HTML-Body
     */
    @ColumnInfo(name = "body")
    var body: String? = null

    /**
     * 圖片作者
     */
    @ColumnInfo(name = "image_source")
    var image_source: String? = null

    /**
     * 詳情頭部image
     */
    @ColumnInfo(name = "image")
    var image: String? = null

    /**
     * 時(shí)間-文字
     */
    @ColumnInfo(name = "date_string")
    var dateString: String = ""

    override fun toString(): String {
        return "StoryEntity(id=$id, images=${Arrays.toString(images)}," +
                " title=$title," +
                " date=$date," +
                " read=$read," +
                " like=$like," +
                " collection=$collection," +
                " body=$body," +
                " image_source=$image_source," +
                " image=$image," +
                " dateString='$dateString')"
    }
}

*** 這里會(huì)遇到【坑1】 Entity類(lèi)需要定義一個(gè)空 構(gòu)造函數(shù)


因?yàn)閟ql中不能插入數(shù)組這樣類(lèi)型數(shù)據(jù),就需要使用到了類(lèi)型轉(zhuǎn)換器了,這里使用了TypeConverters;
關(guān)于寫(xiě)類(lèi)型轉(zhuǎn)換器類(lèi)會(huì)與java不同

/**
 * Created by JokAr on 2017/6/30.
 */
class Converters {
    @TypeConverter
    open fun arrayToString(array: Array<String>): String {
        if (array == null || array.size === 0) {
            return ""
        }

        val builder = StringBuilder(array[0])
        for (i in 1..array.size - 1) {
            builder.append(",").append(array[i])
        }
        return builder.toString()
    }

    @TypeConverter
    open fun StringToArray(value: String): Array<String>? {
        return if (TextUtils.isEmpty(value)) null else value.split(",").toTypedArray()

    }
}

</br>


  • 這里會(huì)遇到【坑2】,看教程里類(lèi)型轉(zhuǎn)換器是使用的靜態(tài)方法的,但是在ktolin若你想使用object 類(lèi)是不行的,使用普通的class類(lèi)就可以了;否則生成文件里會(huì)報(bào)錯(cuò)

</br>

2.創(chuàng)建Dao

/**
 * Created by JokAr on 2017/6/30.
 */
@Dao
interface StoryDao {

    /**
     * 插入story
     */
    @Insert
    fun insert(stories: ArrayList<StoryEntity>)

    /**
     * 根據(jù)時(shí)間獲取story
     */
    @Query("SELECT * FROM story WHERE date = :date ")
    fun getStoryByDate(date: Long): List<StoryEntity>

    /**
     * 獲取所有收藏的story
     */
    @Query("SELECT * FROM story WHERE collection = 1 ")
    fun getAllCollectedStory(): List<StoryEntity>

    /**
     * 更新story
     */
    @Update
    fun updateStory(story: StoryEntity)

    /**
     * 根據(jù)id獲取story
     */
    @Query("SELECT * FROM story where id = :id ")
    fun selectStory(id: Int): StoryEntity
}

</br>


  • 這里會(huì)遇到【坑3】, 方法返回類(lèi)型不能用ArrayList 他會(huì)識(shí)別不了,用List就好了
  • 補(bǔ)充一個(gè) 這里會(huì)遇到【坑4】: insert 的返回值 不能是 Long _impl 生成的是 long 和 kotlin 的Long 類(lèi)型對(duì)不上, 可以用 List<Long> 解決這種尷尬;
      fun insertEntity(vararg entity: UserDBEntity): List<Long>
    

</br>

3.創(chuàng)建Database

@Database(entities = arrayOf(StoryEntity::class,
        TopStoryEntity::class), version = 1)
abstract class AppDataBase : RoomDatabase() {

    abstract fun storyDao(): StoryDao
}

4.創(chuàng)建單例模式使用

class AppDataBaseHelper constructor(context: Context) {

    val appDataBase = Room.databaseBuilder(context, AppDataBase::class.java,
            "daily").build()!!

    companion object {
        @Volatile
        var INSTANCE: AppDataBaseHelper? = null

        fun getInstance(context: Context): AppDataBaseHelper {
            if (INSTANCE == null) {
                synchronized(AppDataBaseHelper::class) {
                    if (INSTANCE == null) {
                        INSTANCE = AppDataBaseHelper(context.applicationContext)
                    }
                }
            }
            return INSTANCE!!
        }
    }

    /**
     * 插入topStory
     */
    fun insertTopStory(topStories: ArrayList<TopStoryEntity>) {
        appDataBase.topStoryDao().insert(topStories)
    }

    /**
     * 根據(jù)時(shí)間獲取story
     */
    fun getStoryByDate(date: Long): ArrayList<StoryEntity> {
        return appDataBase.storyDao().getStoryByDate(date) as ArrayList<StoryEntity>
    }

    /**
     * 根據(jù)id獲取story
     */
    fun getStory(id: Int): StoryEntity{
        return appDataBase.storyDao().selectStory(id)
    }

    /**
     * 更新story;必須在非主線程中進(jìn)行
     */
    fun updateStory(story: StoryEntity) {
        appDataBase.storyDao().updateStory(story)
    }
}

5.坑總結(jié)

  • 【坑1】 Entity類(lèi)需要定義一個(gè)空 構(gòu)造函數(shù)
  • 【坑2】類(lèi)型轉(zhuǎn)換器使用object 類(lèi)是不行的,使用普通的class類(lèi)就可以了;否則生成文件里會(huì)報(bào)錯(cuò)
  • 【坑3】Dao方法返回類(lèi)型不能用ArrayList 他會(huì)識(shí)別不了,用List就好了
  • 【坑4】 insert 的返回值 不能是 Long _impl 生成的是 long 和 kotlin 的Long 類(lèi)型對(duì)不上, 可以用 List<Long> 解決

*暫時(shí)就遇到這么多坑,若再遇到其他會(huì)補(bǔ)充上的;


若想看具體的使用方法,可以參考我的這個(gè)項(xiàng)目

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容