Android jetpack Room的简单使用

文章目录

  • 项目添加ksp插件
  • 添加 room 引用
  • 开始使用room
    • 1. 创建bean
    • 2. 创建 dao类
    • 3. 创建database类
  • 数据库升级
  • 复制数据库到指定路径
  • 参考文献

项目添加ksp插件

注意,因为ksp插件 是跟项目中使用的kotlin的版本要保持一致的,否则会报错的

  1. 首先我们去 https://github.com/google/ksp/releases 看一下目前的ksp 的版本是多少,我当时用的时候的版本是2.0.0-1.0.22,这里的版本数字代表的意思是kotlin的版本是2.0.0,ksp的版本是1.0.22

在这里插入图片描述
2. 我们打开项目的gradle/libs.versions.toml文件,如下,我们看到我们使用的kotlin版本是1.9.0,所以我们需要把kotlin的版本升级成2.0.0
在这里插入图片描述

注意: 如果我们在同步项目的时候发现报如下错误的时候,我们可以在settings.gradle.kts文件中配置阿里的maven

在这里插入图片描述

添加如下代码

pluginManagement {
    repositories {
        ...
        maven { setUrl("https://maven.aliyun.com/nexus/content/groups/public/") }
        maven { setUrl("https://maven.aliyun.com/repository/gradle-plugin") }
        mavenCentral()
        gradlePluginPortal()
    }
}
dependencyResolutionManagement {
    ...
    repositories {
        maven { setUrl("https://maven.aliyun.com/nexus/content/groups/public/") }
        google()
        mavenCentral()
    }
}
  1. 在项目的build.gradle.kts文件中添加引用,如下:
    plugins {
        alias(libs.plugins.androidApplication) apply false
        alias(libs.plugins.jetbrainsKotlinAndroid) apply false
        // apply false 的意思是代表gradle 不会自动应用这个插件,性能优化
        id("com.google.devtools.ksp") version "2.0.0-1.0.22" apply false
    }
    
  2. 在模块的build.gradle.kts文件中添加如下代码。这样ksp插件就引入成功了
    plugins {
        ...
        id("com.google.devtools.ksp")
    }
    

添加 room 引用

  1. 在app的build.gradle.kts文件中添加引用
    dependencies {
    	...
    	implementation("androidx.room:room-runtime:2.6.1")
    	annotationProcessor("androidx.room:room-compiler:2.6.1")
    	// To use Kotlin Symbol Processing (KSP)
    	ksp("androidx.room:room-compiler:2.6.1")
    	// optional - Kotlin Extensions and Coroutines support for Room
    	implementation("androidx.room:room-ktx:2.6.1")
    }
    

在项目中你会遇到如下 黄色警告,可以点击下面的replace,它会自动的给你替换成使用libs.versions.toml的方式来引用

在这里插入图片描述

开始使用room

1. 创建bean

@Parcelize
@Entity(tableName = "person")
data class Person(
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0,
    // 指定数据库表中列的名字,如果不指定就默认使用字段的名字
    @ColumnInfo(name = "name")
    var name: String = "",
    var gender: String = "",
    var telephone: String = "",
    var score: Int = 0,
) : Parcelable

2. 创建 dao类

@Dao
interface PersonDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun addPeople(person: Person)

    @Delete
    fun delPeople(person: Person)

    @Query("delete from person")
    fun delAll()

    @Update
    fun update(person: Person)

    @Query("select * from person order by id asc")
    fun query(): List<Person>

}

3. 创建database类

方式一

@Database(entities = [Person::class], version = 1, exportSchema = false)
abstract class MyDataBase : RoomDatabase() {
    abstract fun personDao(): PersonDao
}

object DataBaseModule {
    fun getDb(
        context: Context
    ) = Room.databaseBuilder(
        context = context,
        MyDataBase::class.java,
        "my_database"
    )
    	//允许在主线程中调用
        //.allowMainThreadQueries()
        .build()

}

方式二

@Database(entities = [Person::class], version = 2, exportSchema = false)
abstract class MyDataBase : RoomDatabase() {

    abstract fun personDao(): PersonDao

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

        fun getInstance(context: Context): MyDataBase? {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    MyDataBase::class.java,
                    "my_database"
                )
               		 //允许在主线程中调用
                    //.allowMainThreadQueries()
                    .build()
                INSTANCE = instance
                INSTANCE
            }
        }

    }

}

数据库升级

  1. 编写Migration
    // 第一种 更新表结构
    val MIGRATION_2_3 = object : Migration(2, 3) {
        override fun migrate(db: SupportSQLiteDatabase) {
            db.execSQL("ALTER TABLE person ADD COLUMN score INTEGER not null default 0")
        }
    }
    
    // 第二种 迁移数据
    val MIGRATION_1_2 = object : Migration(1, 2) {
        override fun migrate(db: SupportSQLiteDatabase) {
            //1.  创建一个新表
            db.execSQL(
                """
                create table person_temp(
                id integer not null primary key autoincrement,
                name text not null ,
                gender text not null,
                telephone text not null,
                score integer not null default 0
                )
            """.trimIndent()
            )
            //2. 迁移数据
            db.execSQL(
                """
                insert into person_temp(name,gender,telephone)
                select name,gender,telephone from person
            """.trimIndent()
            )
            // 3. 删除旧表
            db.execSQL("drop table person")
            // 4. 重新命名新表
            db.execSQL("alter table person_temp rename to person")
        }
    }
    
  2. 在 database类中以addMigrations的方式添加进入
    object DataBaseModule {
        fun getDb(
            context: Context
        ) = Room.databaseBuilder(
            context = context,
            MyDataBase::class.java,
            "my_database"
        )
        	//允许在主线程中调用
            //.allowMainThreadQueries()
            .addMigrations(MIGRATION_1_2)
            .addMigrations(MIGRATION_2_3)
            .build()
    
    }
    

复制数据库到指定路径

CoroutineScope(Dispatchers.IO).launch {
    val writableDatabase = db.openHelper.writableDatabase
    Log.e(TAG, "initListener: ${writableDatabase.path}")
    writableDatabase.path?.apply {
        // 获取数据库文件路径
        val dbFile = File(this)
        // 目标文件路径,你可以自定义路径和文件名
        val path = Environment.getExternalStorageDirectory().absolutePath
        Log.e(TAG, "initListener: $path")
        val targetFile = File(path, "copied_database.db")
        if (targetFile.exists()) {
            targetFile.delete()
        }
        targetFile.createNewFile()

        // 复制数据库文件
        try {
            Log.e(TAG, "initListener: 开始复制")
            val srcChannel: FileChannel = FileInputStream(dbFile).channel
            val dstChannel = FileOutputStream(targetFile).channel
            dstChannel.transferFrom(srcChannel, 0, srcChannel.size())
            srcChannel.close()
            dstChannel.close()
            Log.e(TAG, "initListener: 复制完成")
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }
}

参考文献

1. Room | Jetpack | Android Developer
2. TheRouter 使用 KSP 处理注解
3. Android从Kapt迁移到ksp
4. 可用的KSP的版本

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高德.js2.0绘制多条折线(轨迹)及清除所有折线

2.0版本的地图,需要绘制多条折线的时候,就需要循环生成,因此也需要循环清除 for (let j 0; j < combinedArray.length; j) {const item combinedArray[j];this.polyline new AMap.Polyline({map: this.map,path: item,showDir: true,strokeColor: "#28F", //线…

免费Logo在线生成:必试的6款工具

logo对企业来说非常重要。一个好的logo免费设计在线生成器往往会给企业带来无形的利润。因此&#xff0c;许多企业非常重视自己公司的logo。作为一名设计师&#xff0c;如果能找到一个好的logo免费设计在线生成器&#xff0c;势必会给实际的logo设计带来事半功倍的效果。本文精…

软件测试面试题:Web View如何测试?

Web View介绍 Web View&#xff08;网页视图&#xff09;是一种用于在应用程序中显示网页内容的组件或控件。提供了一种将网页内容嵌入到应用程序中的方式&#xff0c;使用户能够在应用程序中浏览和交互网页。 Web View通常用于开发移动应用程序&#xff0c;特别是混合应用程…

Docker构建多平台镜像

docker的多架构镜像构建 目前很多服务器都是基于arm架构的&#xff0c;而现在大多数的docker镜像都是基于x86架构的。一种情况就是同样的代码编译成业务包做成镜像需要部署在不同架构的服务器上&#xff0c;这个时候我们就可以使用docker的多平台构建了。 以下操作是在centos7.…

Github 2024-06-21 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目3Python项目3Java项目2非开发语言项目2JavaScript项目1Rust项目1Dart项目1HTML项目1Vue项目1C++项目1TensorFlow: 机器学习的开源…

软件自动化测试有哪些流程?可替代手工测试吗?

随着科技的不断发展&#xff0c;软件在我们生活中的地位越来越重要。然而&#xff0c;在软件开发过程中&#xff0c;必然会出现各种各样的问题和bug&#xff0c;为了提高软件的质量和稳定性&#xff0c;保证用户的使用体验&#xff0c;软件自动化测试应运而生。 那么&#xff…

什么是 Azure OpenAI?

目录 一、说明 二、什么是 Azure OpenAI 2.1 网络结构 2.2 、为什么使用 Azure OpenAI 2.3 如何使用 Azure OpenAI 三、从哪里开始 Azure OpenAI 之旅 3.1 关于 Azure OpenAI&#xff0c;我还需要了解什么 3.2 RBAC 权限和角色 3.3 演示 1&#xff1a;在公共数据上应用…

OpenAI封锁中国?国产大模型开启价格战?收好这份LLM选购指南,带你搞定极致性价比 | ShowMeAI

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; 1. Cloud LLM capability, cost, performance | 一份开发者最实用的大模型「性价比」计算手册 这是 Harlan Lewis 整理的大语言模型 (LLM) 对比清单…

深入浅出:npm常用命令详解与实战

theme: smartblue npm是什么 npm&#xff08;Node Package Manager&#xff09;是Node.js平台的默认包管理器&#xff0c;它让JavaScript开发者能够轻松地共享、管理和使用彼此编写的代码模块。npm不仅仅是一个安装工具&#xff0c;它还是一个全面的生态系统&#xff0c;用于发…

为什么要本地化您的多媒体内容?

当我们访问网站、应用程序和社交媒体时&#xff0c;体验不再局限于陈旧的文本和静态图像。现代处理能力和连接速度提高了快速加载视频、音频和动画的可能性。 这一切都提供了更具沉浸感和互动性的用户体验。多媒体是数字营销中最有效的内容之一&#xff0c;因为它对用户更具吸…

笔记本电脑录屏,教你3个方法,简单录屏

随着科技的飞速发展&#xff0c;笔记本电脑录屏功能已经不再局限于传统的录制需求&#xff0c;而是成为了探索屏幕动态的新方式。无论是创意工作者、游戏爱好者还是日常办公者&#xff0c;都可以借助这一功能&#xff0c;将屏幕上的精彩瞬间、重要信息或创新思路记录下来&#…

记录跨度3年的SqlServer数据同步项目分析

目录 技术选型决策阶段 发布订阅 自定义开发 Datax Datax废除主外键关系和自增ID ER模型分组 废掉库表主外键 维度划分Datax任务 基于ID同步 基于TIME时间同步 基于全表ALL同步 废掉自增ID DataX废除主外键关系手动拷贝 手动拷贝 Datax任务分组触发器 Datax全表…

基于Java微信小程序自驾游拼团设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…

深度学习11-20

1.神经元的个数对结果的影响&#xff1a; &#xff08;http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html&#xff09; &#xff08;1&#xff09;神经元3个的时候 &#xff08;2&#xff09;神经元是10个的时候 神经元个数越多&#xff0c;可能会产生…

Django安装与启动

1、Django是什么&#xff1f; 基于python的Web开发框架&#xff0c;支持用户快速开发安全、可维护的网站 2、怎么安装&#xff1f; pip install Django4.2 3、如何启动&#xff1f; 不写ip和端口时候&#xff0c;默认启动http://127.0.0.1:8000/ python .\manage.py runse…

STM32HAL库 -- RS485 开发板通信(速记版)

在本章中&#xff0c; 我们将使用 STM32F429的串口 2 来实现两块开发板之间的 485 通信(半双工)。 RS485 简介 485&#xff08;一般称作 RS485/EIA-485&#xff09;隶属于 OSI 模型物理层&#xff0c;是串行通讯的一种。电气特性规定为 2 线&#xff0c;半双工&#xff0c;多…

基于Java的家教信息管理平台

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

入门篇:创建和运行Hello World

DevEco Studio安装完成后&#xff0c;可以通过运行Hello World工程来验证环境设置是否正确。接下来以创建一个支持Phone设备的工程为例进行介绍。 创建一个新工程 打开DevEco Studio&#xff0c;在欢迎页单击Create Project&#xff0c;创建一个新工程。根据工程创建向导&…

手持小风扇哪个品牌好耐用?手持小风扇品牌排行榜揭晓分享

炎炎夏日&#xff0c;手持小风扇、USB小风扇&#xff0c;成为人手一台的“网红”。这些小风扇造型小巧&#xff0c;可以装进包里&#xff0c;夏日出街或者挤公交地铁都可以拿出来吹一吹。那么这些小风扇性价比高不高呢&#xff1f;真的好用吗&#xff1f;耐用吗&#xff1f;根据…

小程序开发平台源码系统——内容付费(知识付费)小程序功能 带完整的安装代码包以及搭建部署教程

系统概述 随着互联网的发展&#xff0c;人们对于知识和信息的获取需求日益增长。内容付费小程序应运而生&#xff0c;为用户提供了一个便捷、高效的知识交易平台。小程序开发平台源码系统则为开发者提供了构建内容付费小程序的基础和工具&#xff0c;使其能够快速打造具有个性化…