Kotlin + 协程 + Room 结合使用
文章目录
- 前言
- 集成Room
- 结合协程的使用
- 总结
一、前言,
现在kotlin 是趋势,那必然就要用到协程,还有就是随着jetpack 的发力,带来了很多好用的库,比如今天提到Room,是一个类似greenDao的数据库。它不但支持kotlin协程/RxJava,还具备编译期检查,是非常友好的库。我们一起来看下,在项目中怎么使用。
二、集成Room
1、创建一个kotlin项目,然后在app里面的build.gradle添加依赖:
plugins {
...id 'kotlin-android-extensions'id 'kotlin-kapt'
}
dependencies {
...//room数据库implementation "androidx.room:room-runtime:2.4.2"kapt "androidx.room:room-compiler:2.4.2" // Kotlin 使用 kaptimplementation "androidx.room:room-ktx:2.4.2"//Coroutines support for Room 协程操作库//lifecycleimplementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'}
此时,我们同步一下,开始运行项目。会报错:
Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8
解决:将项目的jdk1.8 改成 jdk11。
接下来还有报错:
Can't determine type for tag '<macro name="m3_comp_assist_chip_container_shape">?attr/shapeAppearanceCornerSmall</macro>'
原因是material 的版本高了的问题。
implementation 'com.google.android.material:material:1.8.0'
解决:我们将material,改成1.6.0。项目就能正常运行了。
2、相关的类的创建
2.1创建数据库的实体类
通过在实体类上加注解@Entity,这样实体类就相当于是一张表
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize@Parcelize
@Entity(tableName = "Student")
data class Student(@PrimaryKeyvar id: String,var name: String
) : Parcelable
2.2创建实体类的Dao:
通过在Dao接口上加注解@Dao,就可以让dao轻松地完成增删改查。
另外可以将 suspend Kotlin 关键字添加到 DAO 方法中,用 Kotlin 协程功能,使这些方法成为异步方法。这样可确保不会在主线程上执行这些方法。
@Dao
interface StudentDao {//通过@Insert 注解的onConflict 解决冲突(如果有老的数据存在则会进行替换,如果没有就插入)@Insert(onConflict = OnConflictStrategy.REPLACE)suspend fun putStudent(cacheBean: Student)@Query("select * from Student where id =:id")suspend fun getStudent(id: String): Student?@Query("select * from Student")suspend fun getAllStudent(): List<Student>?@Deletesuspend fun delete(student: Student)@Update(onConflict = OnConflictStrategy.REPLACE)suspend fun update(student: Student)}
2.3 创建数据库的类
创建一个类继承RoomDatabase,加注解@Database,轻松地建数据库和建表
import android.util.Log
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.sqlite.db.SupportSQLiteDatabase//后续的数据库升级通过这个version来控制,exportSchema是否导出数据库的配置信息
@Database(entities = [Student::class], version = 2, exportSchema = false)
abstract class StudentDatabase : RoomDatabase() {companion object {var dataBase: StudentDatabaseval TAG = StudentDatabase::class.java.simpleNameinit {//如果databaseBuilder改为inMemoryDatabaseBuilder则创建一个内存数据库(进程销毁后,数据丢失)dataBase = Room.databaseBuilder(MyApplication.getApplicationContext(), StudentDatabase::class.java, "db_user")//数据库的操作是否允许在主线程中执行.allowMainThreadQueries()//数据库创建和打开后的回调,可以重写其中的方法.addCallback(object : Callback() {override fun onCreate(db: SupportSQLiteDatabase) {super.onCreate(db)Log.d(TAG, "onCreate: db_student")}})//数据库升级异常之后的回滚.fallbackToDestructiveMigration().build()}}abstract fun getStudentDao(): StudentDao
2.4 创建一个MyApplication
通过它我们来获取context。
class MyApplication : Application() {init {instance = this}companion object {private var instance: MyApplication? = nullfun getApplicationContext() : Context {return instance!!.applicationContext}}override fun onCreate() {super.onCreate()}}
三、接下来就是使用了
通过点击按钮,进行增删改查的操作。
增加数据:
btn_add.setOnClickListener {lifecycleScope.launch {val studentDao = StudentDatabase.dataBase.getStudentDao()studentDao.putStudent(Student("101","小李"));studentDao.putStudent(Student("102","小王"))}}
更改数据:
btn_update.setOnClickListener {lifecycleScope.launch {val studentDao = StudentDatabase.dataBase.getStudentDao()val student = studentDao.update(Student("101","小陈"))Log.d(TAG,student.toString());}}
删除数据:
btn_delete.setOnClickListener {lifecycleScope.launch {val studentDao = StudentDatabase.dataBase.getStudentDao()val student = studentDao.delete(Student("101","小陈"))Log.d(TAG,student.toString());val students = studentDao.getAllStudent()Log.d(TAG, "students: $students")}}
查询数据:
lifecycleScope.launch {btn_query.setOnClickListener {lifecycleScope.launch {val studentDao = StudentDatabase.dataBase.getStudentDao()val students = studentDao.getAllStudent()Log.d(TAG, "students: $students")}}
备注:数据库的操作一定要放到子线程中,切不可在主线程中操作,虽然可以通过allowMainThreadQueries强制开启允许这么做,但这个是测试时用,实际项目中还是不要在主线程中操作数据库,避免遇到ANR问题
源码地址:https://github.com/shenshizhong/KotlinRoomDemo
总结
1 、导入依赖, 同步
2 、创建一个实体类Student,加注解@Entity就相当于一张表
3 、创建一个接口StudentDao,加注解@Dao就可以完成增删改查
4 、创建抽象类继承RoomDatabase,加注解@Database,轻松地建数据库和建表
5 、通过数据库的实例获取dao,调用方法
如果对你有一点点帮助,那是值得高兴的事情。:)
我的csdn:http://blog.csdn.net/shenshizhong
我的简书:http://www.jianshu.com/u/345daf0211ad
相关文章:
Kotlin + 协程 + Room 结合使用
文章目录 前言集成Room结合协程的使用总结 一、前言, 现在kotlin 是趋势,那必然就要用到协程,还有就是随着jetpack 的发力,带来了很多好用的库,比如今天提到Room,是一个类似greenDao的数据库。它不但支持kotlin协程…...

网工记背命令(6)----链路聚合配置
目录 1.配置手工负载分担模式链路聚合 2.配置LACP模式的链路聚合 3.HUAWEI设备与C厂商设备对接 链路聚合(Link Aggregation)是将多条物理链路捆绑在一起成为一条逻辑链路,从而增加链路带 宽的技术。 常用配置命令 1、执行命令 interface …...

使用 Service 把前端连接到后端
使用 Service 把前端连接到后端 如何创建前端(Frontend)微服务和后端(Backend)微服务。后端微服务是一个 hello 欢迎程序。 前端通过 nginx 和一个 Kubernetes 服务暴露后端所提供的服务。 使用部署对象(Deployment ob…...
vue 如何优化首页的加载速度?vue 首页白屏是什么问题引起的?如何解决呢?
vue 如何优化首页的加载速度? 路由懒加载ui框架按需加载gzip压缩 vue首页白屏是什么问题引起的 第一种,打包后文件引用路径不对,导致找不到文件报错白屏 解决办法:修改一下config下面的index.js中bulid模块导出的路径。因为in…...

Android平台GB28181设备接入模块之SmartGBD
大牛直播SDK研发的Android平台GB28181设备接入SDK(SmartGBD),可实现不具备国标音视频能力的 Android终端,通过平台注册接入到现有的GB/T28181—2016服务,可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育…...
JVM第十三讲:调试排错 - JVM 调优参数
调试排错 - JVM 调优参数 本文是JVM第十三讲,调试排错 - JVM 调优参数。对JVM涉及的常见的调优参数和垃圾回收参数进行阐述。 文章目录 调试排错 - JVM 调优参数1、Jvm参数2、垃圾回收 问题1:线上ECS治理问题2:白龙马线上服务机JVM参数配置&a…...

Android Gradle权威指南读书笔记
第一章 Gradle入门 生成Gradle Wrapper 命令:gradle wrapper --gradle-version 版本号自定义Gradle Wrapper task wrapper(type : Wrapper) { gradleVersion 2.4 archiveBase GRADLE USER HOME archivePath wrapper/dists distributionBase GRADLE USER HOME …...
顺子日期(蓝桥杯)
文章目录 顺子日期问题描述答案:14字符串解题CC语言指针C语言函数 数组解题 顺子日期 问题描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 小明特别喜欢顺子。顺子指的就是连续的三个数字:123、…...

攻防世界web篇-unserialize3
得出php代码残篇 将代码补全后再在线php运行工具中进行运行 在浏览器输入后得到下面的界面 这里需要将O:4:“xctf”:1:{s:4:“flag”;s:3:“111”;} 改为 O:4:“xctf”:2:{s:4:“flag”;s:3:“111”;}...
微信小程序 onLoad和onShow的区别
在微信小程序中,onLoad() 和 onShow() 是两个常用的生命周期函数,用于监听页面的加载和显示事件。这两个函数的区别如下: 触发时机 onLoad() 函数只会在页面加载时触发一次,而 onShow() 函数每次页面显示时都会被触发。因此&#…...

elementui select组件下拉框底部增加自定义按钮
elementui select组件下拉框底部增加自定义按钮 el-select组件的visible-change 事件(下拉框出现/隐藏时触发) <el-selectref"select":value"value"placeholder"请选择"visible-change"visibleChange">&…...
深入理解闭包:原理、应用与最佳实践
1、 什么是闭包? 如果一个函数内部定义了另一个函数,并且内部函数引用了外部函数的变量,那么内部函数就形成了一个闭包。 def outer_function(x):# 外部函数接受一个参数 x 是自由变量# seed 也是一个自由变量seed 10def inner_function(y…...
[NSSCTF 2nd]Math
原题py: from secret import flag from Crypto.Util.number import * import gmpy2length len(flag) flag1 flag[:length//2] flag2 flag[length//2:] e 65537m1 bytes_to_long(flag1) p getPrime(512) q getPrime(512) n p*q phi (p-1)*(q-1) d gmpy2.i…...

uml知识点学习
https://zhuanlan.zhihu.com/p/659911315https://zhuanlan.zhihu.com/p/659911315软件工程分析设计图库目录 - 知乎一、结构化绘图1. 结构化——数据流图Chilan Yuk:1. 结构化——数据流图2. 结构化——数据字典Chilan Yuk:2. 结构化——数据字典3. 结构…...

JAVA学习日记1——JAVA简介及第一个java程序
简单记忆 JAVA SE :标准版,核心基础 JAVA EE:企业版,进阶 JDK:Java Development Kit,Java开发工具包,包含JRE JRE:Java Runtime Environment,Java运行时环境ÿ…...
Linux命令(102)之less
linux命令之less 1.less介绍 linux命令less是一个文本文件查看工具,它以一种交互的方式,逐页地显示文本文件的内容,并且可以在文件中进行搜索等定位 2.less用法 less [参数] filename less参数 参数说明-N显示每行的行号-i忽略搜索时的大…...
vue多条件查询
<template><div><input type"text" v-model"keyword" placeholder"关键字"><select v-model"category"><option value"">所有分类</option><option v-for"cat in categories&q…...
c 语言基础:L1-038 新世界
这道超级简单的题目没有任何输入。 你只需要在第一行中输出程序员钦定名言“Hello World”,并且在第二行中输出更新版的“Hello New World”就可以了。 输入样例: 无输出样例: Hello World Hello New World 程序源码: #incl…...

计算机算法分析与设计(13)---贪心算法(多机调度问题)
文章目录 一、问题概述1.1 思路分析1.2 实例分析 二、代码编写 一、问题概述 1.1 思路分析 1. 设有 n n n 个独立的作业 1 , 2 , … , n {1, 2, …, n} 1,2,…,n,由 m m m 台相同的机器 M 1 , M 2 , … , M m {M_1, M_2, …, M_m} M1,M2,…,Mm 进行加工处…...

小程序canvas层级过高真机遮挡组件的解决办法
文章目录 问题发现真机调试问题分析问题解决改造代码效果展示 问题发现 在小程序开发中需要上传图片进行裁剪,在实际真机调试中发现canvas层遮挡住了生成图片的按钮。 问题代码 <import src"../we-cropper/we-cropper.wxml"></import> <…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...