Jetpack 中 room 基本使用

Room 概述

Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库,具体来说,Room具有一下优势:

1、针对SQL 查询的编译时验证。

2、可最大限度减少重复和容易出错的样板代码的方便注解。

3、简化了数据库迁移路径。

build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
}

dependencies {   
    // Room
    implementation "androidx.room:room-ktx:2.4.1"
    kapt "androidx.room:room-compiler:2.4.1"

    //ViewModelScope + LifecycleScope + liveData
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
    //json解析
    implementation 'com.alibaba:fastjson:1.2.58'
}

主要组件

Room 包含三个主要组件:

1、数据库类,用于保存数据库并作用应用持久性数据底层连接的主要访问点。

2、数据实体,用于表示应用的数据库中的表。

3、数据访问对象(DAO),提供您的应用可用于查询、更新、插入和删除数据库中的数据的方法。

数据库类为应用提供与该数据库关联的 DAO 的实例。反过来,应用可以使用 DAO 从数据库中检索数据,作为关联数据实体对象的实例。此外,应用还可以使用定义的数据实体更新相对应表中的行,或者创建新行供插入。图1说明了 Room 的不同组件之间的关系。

数据实体

@Entity(tableName = "word_table")
data class Word(
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    var id: Int = 0,

    @ColumnInfo(name = "word")
    val word: String
)

@Entity 使用 Room 定义一个数据实体 Word (带 Entity 注解的类),一个 Entity 表由主键和一个或者多个列组成,Word 中的每一个实例都代表着 word_table 中的一行,tableName 后面为表名,在不指定表名的情况下,默认将类名作为数据表的名称。Room默认使用字段名称作为列名称,如需更改,采用 @ColumnInfo注解设置 name 属性(列名)。

数据访问对象 (DAO)

@Dao
interface WordDao {

    @Query("SELECT * FROM word_table ORDER BY word ASC")
    suspend fun getAlphabetizedWords(): List<Word>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(word: Word)

    @Query("DELETE FROM word_table")
    suspend fun deleteAll()
}

定义了一个 WordDao 的 DAO 。WorDao 提供了应用的其余部分用于与 word 表中的数据交互方法。

数据库

@Database(entities = [Word::class], version = 2)
abstract class AppDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "word_database"
                )
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
    }
}

定义用于保存数据库的 AppDatabase 类,AppDatabase 定义数据库配置,并作为应用对持久性数据的主要访问点,数据库类必须满足一下条件:

1、该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组。

2、该类必须是一个抽象类,用于扩展 RoomDatabase.

3、对于与数据库关联的每一个 DAO类,数据库类必须定义一个具有零参数的抽象方法,并返回 DAO 类的实例。

MainActivity 使用

class MainActivity : AppCompatActivity() {

    lateinit var database: AppDatabase

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        database = AppDatabase.getDatabase(this)

        findViewById<Button>(R.id.btn1).setOnClickListener {
            lifecycleScope.launch {
                database.wordDao().insert(Word(word = "long"))
                database.wordDao().insert(Word(word = "long"))
                database.wordDao().insert(Word(word = "long"))
            }
        }
        findViewById<Button>(R.id.btn2).setOnClickListener {
            lifecycleScope.launch {
                val list = database.wordDao().getAlphabetizedWords();
                Log.i("TAG", JSON.toJSONString(list))
            }
        }
    }
}

数据库迁移

@Database(entities = [Word::class, Device::class], version = 6)
abstract class AppDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao
    abstract fun deviceDao(): DeviceDao

    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null

        fun getDatabase(context: Context): AppDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "word_database"
                )
                    .fallbackToDestructiveMigration()
                    .addMigrations(object : Migration(3, 4) {
                        override fun migrate(database: SupportSQLiteDatabase) {
                            //将数据表device创建出来
                            database.execSQL("CREATE TABLE 'device' ('id'  TEXT,'location' TEXT,'deviceName' TEXT,'deviceType' TEXT,PRIMARY KEY ('id')) ");
                        }
                    },object :Migration(4,5){
                        override fun migrate(database: SupportSQLiteDatabase) {
                            //为device表增加一列
                            database.execSQL("ALTER TABLE device ADD COLUMN deviceCode TEXT NOT NULL DEFAULT 'a'");
                        }

                    },object :Migration(5,6){
                        override fun migrate(database: SupportSQLiteDatabase) {
                            //为device表增加一列
                            database.execSQL("ALTER TABLE device ADD COLUMN deviceManager TEXT NOT NULL DEFAULT 'A类型'");
                        }

                    })
                    .build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
    }
}

 addMigrations 增加对应升级的策略

参考:

使用 Room 将数据保存到本地数据库  |  Android 开发者  |  Android Developers

Android jetpack Room数据库(二)版本升级/迁移_java.lang.illegalstateexception: a migration from _肖波86440的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值