Jetpack 中 room 基本使用

news2024/10/7 19:23:42

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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/988979.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三、创建各个展示模块组件

简介 在文件 components 中创建轮播模块组件,引入App.vue展示。欢迎访问个人的简历网站预览效果 本章涉及修改与新增的文件:First.vue、Second.vue、Third.vue、Fourth.vue、Fifth.vue、App.vue、vite-env.d.ts、assets 一、修改vite-env.d.ts文件 /// <reference type…

Linux-Shell整理集合

Shell变量 参考文章&#xff1a; Shell脚本中变量的使用 shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 参考文章&#xff1a; shell语法之 , ‘ ‘ , {},, ,‘‘,(),$(())四种语法含义 grep常用用法 Shell awk命令详解 grep 跟awk连着用&#xff1a; 获取某程序的…

索尼 toio™应用创意开发征文|联盟国战

✨ 能用众力&#xff0c;则无敌于天下矣&#xff1b;能用众智&#xff0c;则无畏于圣人矣。 —— 孙权 前言&#xff1a; 从火爆全网的ChatGPT&#xff0c;到人人都是开发者。AI无疑贯彻了整个2023年的主题&#xff0c;从刚上幼儿园的小朋友到耄耋之年的老顽童&#xff0c;都对…

Meta 验证徽章:为何大家都想在 FB 和 IG 上获得元验证

随着 Meta&#xff08;前身为 Facebook&#xff09;和 Instagram 统治数字领域&#xff0c;Meta Verified 徽章已成为真实性的终极象征。无论您是公众人物还是品牌&#xff0c;在Facebook和Instagram上获得此徽章都会对您的在线形象产生深远的影响。Facebook验证于2013年首次推…

【Python程序设计】Python 中的环境变量【05/8】

一、说明 以下文章是有关 Python 数据工程系列文章的一部分&#xff0c;旨在帮助数据工程师、数据科学家、数据分析师、机器学习工程师或其他刚接触 Python 的人掌握基础知识。本篇将讲述环境变量的问题。 迄今为止&#xff0c;本初学者指南包括&#xff1a; 第 1 部分&#xf…

算法的时间及空间复杂度

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

thinkPhp5返回某些指定字段

//去除掉密码$db new UserModel();$result $db->field(password,true)->where("username{$params[username]} AND password{$params[password]}")->find(); 或者指定要的字段的数组 $db new UserModel();$result $db->field([username,create_time…

AList dokcer安装及百度网盘挂载

AList是开源的网盘管理工具。本文介绍如何通过docker安装AList并挂载百度网盘 1、AList安装 1.1、系统安装 通过docker命令进行安装&#xff0c;命令如下: docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 --name"alist" xhofe/alist:…

学生来看!如何白嫖内网穿透?点进来!

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1 搭建虚拟机1.1 下载文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压虚拟机文件1.4 虚拟机初始化1.5 没有搜索到解决方式&#xff1a;1.6 虚…

End-to-End Object Detection with Transformers(论文解析)

End-to-End Object Detection with Transformers 摘要介绍相关工作2.1 集合预测2.2 transformer和并行解码2.3 目标检测 3 DETR模型3.1 目标检测集设置预测损失3.2 DETR架构 摘要 我们提出了一种将目标检测视为直接集合预测问题的新方法。我们的方法简化了检测流程&#xff0c…

第三方软件信息安全测评服务范围

安全测试 第三方软件信息安全cnas资质测评服务范围&#xff1a; 1、信息安全风险评估 依据《GB/T 20984-2007 信息安全技术信息安全风险评估规范》&#xff0c;通过风险评估项目的实施&#xff0c;对信息系统的重要资产、资产所面临的威胁、资产存在的脆弱性、已采取的防护措…

企业架构LNMP学习笔记24

学习目标和内容&#xff1a; 1、能够描述高可用HA的作用 2、能够理解VIP的切换&#xff1a;虚拟IP。 3、能够描述keepalived作用&#xff1a;保持活跃。主备的服务器的关系。 4、能够理解主master和备backup服务器关系 5、能够实现主备服务器高可用配置&#xff1a;主服务…

合宙Air724UG LuatOS-Air LVGL API控件-开关 (Switch)

开关 (Switch) 示例代码 function event_handler(obj, event)if event lvgl.EVENT_VALUE_CHANGED thenprint("State", lvgl.switch_get_state(obj))end endsw1 lvgl.switch_create(lvgl.scr_act(), nil) lvgl.obj_align(sw1, nil, lvgl.ALIGN_CENTER, 0, -50) lvg…

超强大JS表格:DataViewsJS 1.8.16.1407 Crack

DataViewsJS完整的 JavaScript 数据呈现和数据网格平台 通过从各种不同的演示视图中进行选择&#xff0c;包括树、卡片、砖石、网格、时间线、甘特图、日历和网格&#xff0c;超越传统的表格显示。 快速地&#xff01;纯 JavaScript&#xff0c;针对速度进行了优化 从多种视图中…

数据结构与算法_树和二叉树

目录 一、树的概念 二、树的衍生概念 三、二叉树 顺序结构 链式存储 二叉树连式结构的遍历 一、树的概念 树是一种非线性的数据结构&#xff0c;它由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。 在树中&#xff0c;有一个特殊节点成为根节…

【GO语言基础】前言

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 【GO语言基础】运算符 文章目录 系列文章目录一、基础知识包和函数函数声明语法简洁性 括号成对出现GO常用DOS命令命名规则项目目录结构注释 总结 一、基础知识 …

The Sandbox 中的建设者:走进 Sandja Studio

随着 The Sandbox 出版新功能的到来&#xff0c;来自世界各地的熟练建设者正在完成必要的步骤&#xff0c;推出他们的可玩体验并与社区分享。 在本期的《The Sandbox 建设者》中&#xff0c;我们将与Sandja Studio一起讨论他们的《星际考古学家》体验。 Sandja Studio 是一家…

ARM接口编程—UART(exynos 4412平台)

UART简介 UART Universal Asynchronous Receiver Transmitter即通用异步收发器&#xff0c;是一种通用的串行、异步通信总线该总线有两条数据线&#xff0c;可以实现全双工的发送和接收在嵌入式系统中常用于主机与辅助设备之间的通信 波特率 波特率用于描述UART通信时的通信…

企业架构LNMP学习笔记25

高可用服务搭建&#xff1a; HA高可用&#xff1a;是一个解决方案。 高可用HA&#xff08;High Availability&#xff09;是分布式系统架构中必须考虑的因素之一。它通常是指通过设计&#xff0c;减少系统服务不可用的时间&#xff0c;假设系统一直能够提供服务&#xff0c;我…