当前位置: 首页 > news >正文

Android笔记(二十一):Room组件实现Android应用的持久化处理

一、Room组件概述

Room是Android JetPack架构组件之一,是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层,使之实现数据访问。
在这里插入图片描述

(1)实体类(Entity):映射并封装了数据库对应的数据表中对应的结构化数据。实体定义了数据库中的数据表。实体类中的数据域与表的列一一对应。
(2)数据访问对象(Data Access Object,DAO):在DAO中定义了访问数据库的常见的操作(例如插入、删除、修改和检索等),以达到实现创建映射数据表的实体类对象,以及对该实体类对象实例的属性值进行设置和获取的目的。
(3)数据库(Room Database):表示对数据库基本信息的描述,包括数据库的版本、名称、包含的实体类和提供的DAO对象实例。Room组件中的所有的数据库必须扩展为RoomDatabase抽象类,从而实现对实际SQLite数据库的封装。

二、Room组件的配置

在移动应用所在的模块对应的build.gradle中需要进行如下配置:

(1) 增加插件

Groovy DSL:

plugins {……id 'kotlin-kapt'
}

Kotlin DSL:

plugins{
...id("kotlin-kapt")
}

kotlin-kapt实现标注(注解)处理

(2)增加标注处理的配置

Groovy DSL定义:

android {……defaultConfig {……//增加标注处理,增加Schema保存的路径javaCompileOptions{annotationProcessorOptions{//定义标注处理器选项arguments +=["room.schemaLocation":"$projectDir/schemas".toString(),"room.incremental":"true","room.expandProjection":"true"]}}
}

Kotlin DSL定义:

android {……defaultConfig {……//增加标注处理javaCompileOptions{annotationProcessorOptions{//定义标注处理器选项arguments +=mapOf("room.schemaLocation" to "$projectDir/schemas".toString(),"room.incremental" to "true","room.expandProjection" to "true")}}
}

(3)增加相关依赖

Groovy DSL定义

    def room_version = "2.5.0"implementation"androidx.room:room-runtime:$room_version"// 注释处理工具annotationProcessor "androidx.room:room-compiler:$room_version"// Kotlin注释处理工具(kapt)kapt"androidx.room:room-compiler:$room_version"// kotlin扩展和协同程序对Room的支持implementation "androidx.room:room-ktx:$room_version"

如果在处理数据库是需要采用rxJava3来实现异步处理,这时还需要增加RxJava3库

    //增加RxJava库的依赖implementation "io.reactivex.rxjava3:rxjava:3.0.7"//增加在Android对RxJava库的支持implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'// RxJava3implementation "androidx.room:room-rxjava3:$room_version"

Kotlin DSL定义依赖:

    val room_version = "2.5.0"implementation("androidx.room:room-runtime:$room_version")annotationProcessor("androidx.room:room-compiler:$room_version")kapt("androidx.room:room-compiler:$room_version")// kotlin扩展和协同程序对Room的支持implementation("androidx.room:room-ktx:$room_version")// RxJava2implementation("androidx.room:room-rxjava2:$room_version")// RxJava3implementation("androidx.room:room-rxjava3:$room_version")//增加RxJava库的依赖implementation("io.reactivex.rxjava3:rxjava:3.0.7")//增加在Android对RxJava库的支持implementation("io.reactivex.rxjava3:rxandroid:3.0.0")

如果在构建模块的过程中,出现了java版本不兼容的情况,可以调整:

android{
...compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}
}

三、Room组件实现数据库的处理

新建一个项目,实现对多位学生的信息写入数据库并执行检索和CRUD操作。

3.1 创建实体类

映射并封装了数据库对应的数据表中对应的结构化数据。实体定义了数据库中的数据表。实体类中的数据域与表的列一一对应。

@Entity(tableName = "students")
data class Student(@PrimaryKey(autoGenerate = true)@ColumnInfo(name= "studentId") val id:Long,@ColumnInfo(name= "studentNo") val no:String?,@ColumnInfo(name= "studentName") val name:String,@ColumnInfo(name= "studentScore") val score:Int,@ColumnInfo(name = "studentGrade") val grade:String?)
{@Ignoreconstructor(no:String,name:String,score:Int,grade:String):this(0,no,name,score,grade)
}

定义的实体类Student与数据表students对应。通过标注@Entity(tableName = “students”)来指定实体类对应的数据表。并对实体类的属性定义通过标注@ColumnInfo,对应于数据表students中的各个字段,并通过@PrimaryKey标注来指定数据表的关键字。

注意:Room只能识别和使用一个构造器,如果存在多个构造器可以使用@Ignore让Room忽略这个构造器。因此在上述代码中constructor定义的辅助构造器增加了标注@Ignore。

3.2 创建数据访问对象DAO

在数据访问对象DAO是一个接口,定义了对指定数据表希望能执行的CRUD操作。

@Dao
interface StudentDAO {/*** 插入记录*/@Insertfun insertStudent(student:Student):Long/*** 删除记录*/@Updatefun updateStudent(student:Student)/*** 删除记录*/@Deletefun deleteStudent(student:Student)/*** 检索所有的记录*/@Query("select * from students")fun queryAllStudents():List<Student>/*** 检索指定学号的学生记录*/@Query("select * from students where studentNo = :no")fun queryStudentByNo(no:String):Student}

3.3 创建数据库

必须定义一个RoomDatabase的抽象子类来表示对数据库基本信息的描述,包括数据库的版本、名称、包含的实体类和提供的DAO对象实例。通过数据库类来达到对实际SQLite数据库的封装。

@Database(entities = [Student::class], version = 1)
abstract class StudentDatabase : RoomDatabase() {abstract fun studentDao(): StudentDAOcompanion object{private var instance: StudentDatabase? = null/*** 单例模式创建为一个StudentDatabase对象实例*/@Synchronizedfun getInstance(context: Context): StudentDatabase {instance?.let{return it}return Room.databaseBuilder(context,StudentDatabase::class.java,"studentDB.db").build()}}
}

@Database标注表示抽象的类对应数据库,内部包括的数据表由标注内部的属性entities指定。如果数据库包括多个数据表,entitites可以指定多个实体类的类对象。
在上述的代码中,采用了单例模式,使得在整个移动应用中只有一个数据库的对象实例,在获取这个唯一实例时,只有一个线程可以访问,因此在getInstance方法中设置标注@Synchronized。在这个方法指定创建的数据库名是studentDB.db

3.4 定义并配置应用类

因为在应用中需要获取上下文,因此定义应用类,并在AndroidManifest进行配置,使之易于获取applicationContext上下文对象。

3.4.1定义应用类

class MainApp: Application() {@SuppressLint("StaticFieldLeaked")companion object{lateinit var context: Context}override fun onCreate() {super.onCreate()context = applicationContext}
}

3.4.2 在AndroidManifest.xml配置应用类

在AndroidManifest.xml中需要在application元素中指定已定义的应用类MainApp,类似如下代码

 <?xml version="1.0" encoding="utf-8"?>   <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application  android:name=".MainApp"  ... > 
</application>    
</manifest>  

3.5 测试数据库的访问

在MainActivity中定义对数据库的测试代码。

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {testDB()}}/*** 测试数据库*/fun testDB() {Observable.create<Student> { emitter ->//获得Dao对象val dao = StudentDatabase.getInstance(MainApp.context).studentDao()//插入记录,测试数据库版本,将下列注释取消dao.insertStudent(Student("6001013", "李四", 87, "良好"))//检索记录val students = dao.queryAllStudents()for (student in students)emitter.onNext(student)}.subscribeOn(Schedulers.io())//指定被观察者的线程处理I/O 操作.observeOn(AndroidSchedulers.mainThread())//指定观察者的线程为主线程.subscribe {Log.d("Ch10_05", "${it}")}}
}

四、Room组件实现数据库的迁移

移动应用的需求的变化,也会导致数据库不断地升级。在数据库升级时,会希望保留原有的数据。因此,Room提供了数据库迁移的方式来解决数据库的升级。

Room库提供了Migration 类实现数据库增量迁移。每个 Migration 子类提供了Migration.migrate() 函数实现新旧版本数据库之间的迁移路径。当移动应用需要升级数据库时,Room 库会利用一个或多个 Migration 子类运行 migrate() 函数,在运行时将数据库迁移到最新版本。

在上述的模块的基础上,要求修改数据库中数据表students的结构,增加一个新的字studentAddress,这时需要修改上述代码来完成具体的功能。

4.1 修改实体类

修改实体类Student,增加一个属性address,并映射数据表students的字段studentAddress,代码如下:

@Entity(tableName = "students")
data class Student(@PrimaryKey(autoGenerate = true)@ColumnInfo(name="studentId") val id:Long,@ColumnInfo(name="studentNo") val no:String?,@ColumnInfo(name="studentName") val name:String,@ColumnInfo(name="studentScore") val score:Int,@ColumnInfo(name = "studentGrade") val grade:String?,@ColumnInfo(name="studentAddress") val address:String?){@Ignoreconstructor(no:String,name:String,score:Int,grade:String,address:String):this(0,no,name,score,grade,address)
}

4.2 修改数据库

因为数据表变化,这时需要修改数据库,变更数据库的版本为2。定义Migration对象,指定数据库迁移是从版本1迁移到版本2,并覆盖migrate的方法,执行具体迁移的操作。

@Database(entities = [Student::class], version = 2)
abstract class StudentDatabase : RoomDatabase() {abstract fun studentDao(): StudentDAOcompanion object{private var instance: StudentDatabase? = null//数据库从版本1迁移到版本2val MIGRATION_1_2 = object : Migration(1, 2) {//迁移方法定义override fun migrate(database: SupportSQLiteDatabase) {//修改数据表students,增加一个新的字段address,数据类型为TEXT字符串database.execSQL("ALTER TABLE students ADD COLUMN studentAddress TEXT")}}/*** 单例模式创建为一个StudentDatabase对象实例*/@Synchronizedfun getInstance(context:Context):StudentDatabase{instance?.let{return it}return Room.databaseBuilder(context,StudentDatabase::class.java,"studentDB.db").addMigrations(MIGRATION_1_2).build().apply{instance = this}}}
}

在上述代码的getInstance返回数据库对象时,通过调用addMigrations进行处理迁移的操作。

4.3 修改测试代码

在上述修改的前提基础上,因数据库的变更,测试代码也进行修改,代码如下:

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {testDB()}}/*** 数据库版本2的测试函数*/fun testDB(){Observable.create<Student>{ emitter ->//获得Dao对象val dao = StudentDatabase.getInstance(MainApp.context).studentDao()//插入记录dao.insertStudent(Student("6001015","王五",87,"良好","江西省南昌红谷大道999号"))//检索记录val students = dao.queryAllStudents()for(student in students)emitter.onNext(student)}.subscribeOn(Schedulers.io())//指定被观察者的线程处理I/O 操作.observeOn(AndroidSchedulers.mainThread())//指定观察者的线程为主线程.subscribe{ it: Student ->Log.d("TAG","${it}")}}
}

参考文献

陈轶《Android移动应用开发(微课版)》[M] 北京:清华大学出版社 2022 P407-P419

相关文章:

Android笔记(二十一):Room组件实现Android应用的持久化处理

一、Room组件概述 Room是Android JetPack架构组件之一&#xff0c;是一个持久处理的库。Room提供了在SQLite数据库上提供抽象层&#xff0c;使之实现数据访问。 &#xff08;1&#xff09;实体类&#xff08;Entity&#xff09;&#xff1a;映射并封装了数据库对应的数据表中…...

uniapp中各种状态的按钮

当涉及状态按钮时&#xff0c;UniApp提供了丰富的选择。UniApp中的状态按钮可以是开关按钮、单选按钮、多选按钮等。开发者可以根据具体需求选择使用合适的状态按钮组件。对于状态按钮&#xff0c;UniApp提供了丰富的API和事件&#xff0c;可以轻松实现状态切换、状态监听等功能…...

模式识别与机器学习-判别式分类器

模式识别与机器学习-判别式分类器 生成式模型和判别式模型的区别线性判别函数多分类情况多分类情况1多分类情况2多分类情况3 例题 广义线性判别函数实例 分段线性判别函数Fisher线性判别感知机算法例&#xff1a;感知机多类别分类 谨以此博客作为学习期间的记录 生成式模型和判…...

c++11 标准模板(STL)(std::pair)(七)访问 pair 的一个元素

定义于头文件 <utility> std::pair 是一个结构体模板&#xff0c;其可于一个单元存储两个相异对象。 pair 是 std::tuple 的拥有两个元素的特殊情况。 访问 pair 的一个元素 std::get(std::pair) template< size_t I, class T1, class T2 > typename std::tuple…...

IP 地址归属地查询

IP 地址归属地查询 1. IP 地址归属地查询2. IP 地址归属地查询References 1. IP 地址归属地查询 https://tool.lu/ip/index.html 2. IP 地址归属地查询 https://www.ip.cn/ip/.html References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...

实战经验分享:在Java中灵活应用Excel注释和批注

本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 注释及批注是 Excel 中比较常用的功能&#xff0c;注释往往针对单元格&#xff0c;起到解释说明的作用&a…...

AUTOSAR从入门到精通-车载以太网(三)

目录 前言 原理 车载以太网总体架构 物理层 数据链路层 以太网帧格式<...

【自然语言处理】用Python从文本中删除个人信息-第二部分

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…...

设计模式之-中介者模式,快速掌握中介者模式,通俗易懂的讲解中介者模式以及它的使用场景

系列文章目录 设计模式之-6大设计原则简单易懂的理解以及它们的适用场景和代码示列 设计模式之-单列设计模式&#xff0c;5种单例设计模式使用场景以及它们的优缺点 设计模式之-3种常见的工厂模式简单工厂模式、工厂方法模式和抽象工厂模式&#xff0c;每一种模式的概念、使用…...

12.25

led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…...

MySQL5.7的几种安装方式总结(排错踩坑呕心沥血的经历)

包安装 添加国内源&#xff1a;mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror 注意&#xff1a;5.7安装之后有一个临时密码&#xff0c;进行登录并修改新密码后才可以对mysql进行操作。 可以yun list看看各个系统光盘自带的都是什么版本&…...

zookeeper基本使用

目录 环境搭建 单机版搭建 集群版搭建 基本语法使用 可视化客户端 数据结构 节点分类 1. 持久节点 2. 临时节点 3. 有序节点 4. 容器节点 5. TTL节点 节点状态 监听机制 watch监听 永久性watch 应用场景 1. 实现分布式锁 2. 乐观锁更新数据 应用场景总结 选…...

【华为机试】2023年真题B卷(python)-分月饼

一、题目 题目描述&#xff1a; 中秋节公司分月饼&#xff0c;m个员工&#xff0c;买了n个月饼&#xff0c;m<n&#xff0c;每个员工至少分1个月饼&#xff0c;但可以分多个&#xff0c;单人份到最多月饼的个数为Max1&#xff0c;单人分到第二多月饼的个数是Max2&#xff0c…...

EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析

EtherCAT主站SOEM -- 11 -- EtherCAT从站 XML 文件解析 1 EtherCAT 从站信息规范1.1 XML 文件说明1.1.1 XML 数据类型1.1.2 EtherCATInfo1.1.3 Groups1.1.4 Devices1.1.5 Modules1.1.6 Types1.1.6.1 AccessType 的组成1.1.6.2 ArraylnfoType 的组成1.1.6.3 DeviceType 的组成1.…...

YOLOv5算法改进(23)— 更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv

前言:Hello大家好,我是小哥谈。本节课就让我们结合论文来对YOLOv5进行组合改进(更换主干网络GhostNet + 添加CA注意力机制 + 引入GhostConv),希望同学们学完本节课可以有所启迪,并且后期可以自行进行YOLOv5算法的改进!🌈 前期回顾: YOLOv5算法改进(1)— 如何去…...

centos系统部署rancher1.6版本并部署服务

1. centos上部署docker. 请参考 博客 2. 用docker安装rancher1.6 sudo docker run -d -v /mnt/rancher/db:/var/lib/mysql --restartunless-stopped -p 8080:8080 rancher/server3.浏览器登录做设置 3.1 浏览器打开 1.117.92.32:8080 #直接就登录了 3.2 第一次进入&am…...

Matlab实时读取串口数据并实时画图方法

** Matlab实时读取串口数据并实时画图方法 ** 按照数据串口协议如&#xff1a;$KT2,1.80,88.18,39.54,42.86,LO[0.72,-1.04,0.35]&#xff0c;举例。 s serialport("COM12",115200,"Timeout",5); poszeros(100000,3); j1; data1 read(s,1,"uint8&…...

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.向量加权平均算法4.实验参数设定…...

SpringBoot - Maven 打包合并一个胖 JAR 以及主项目 JAR 依赖 JAR 分离打包解决方案

问题描述 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><!--<classifier>exec</classifier>--…...

react 18 Hooks扩展函数式组件的状态管理

React函数式组件 特点 React函数式组件具有以下特点&#xff1a; 简洁&#xff1a;使用函数的方式定义组件&#xff0c;语法简单直观。无状态&#xff1a;函数式组件没有内部状态&#xff08;state&#xff09;&#xff0c;只依赖于传入的props。可复用&#xff1a;函数式组…...

智能优化算法应用:基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.浣熊算法4.实验参数设定5.算法结果6.参考文献7.MA…...

c++ qt QtWidgetsApplication 项目 使用外部ui

1 包含生成的UI头文件&#xff1a; 例如&#xff0c;如果你的Qt Designer的.ui文件名为test.ui&#xff0c;那么生成的头文件通常为ui_test.h。 #include "ui_test.h"2 实例化UI类&#xff1a;.h文件中实例化ui 在你的主要类的头文件中&#xff0c;你通常会声明一个U…...

使用React 18、Echarts和MUI实现温度计

关键词 React 18 Echarts和MUI 前言 在本文中&#xff0c;我们将结合使用React 18、Echarts和MUI&#xff08;Material-UI&#xff09;库&#xff0c;展示如何实现一个交互性的温度计。我们将使用Echarts绘制温度计的外观&#xff0c;并使用MUI创建一个漂亮的用户界面。 本文…...

使用代码生成工具快速开发应用-结合后端Web API提供接口和前端页面快速生成,实现通用的业务编码规则管理

1、通用的业务编码规则的管理功能 在前面随笔我们介绍了一个通用的业务编码规则的管理功能&#xff0c;通过代码生成工具Database2Sharp一步步的生成相关的后端和Winform、WPF的界面&#xff0c;进行了整合&#xff0c;通过利用代码生成工具Database2sharp生成节省了常规功能的…...

Android 13 - Media框架(26)- OMXNodeInstance(三)

上一节我们了解了OMXNodeInstance中的端口定义&#xff0c;这一节我们一起来学习ACodec、OMXNode、OMX 组件使用的 buffer 到底是怎么分配出来的&#xff0c;以及如何关联起来的。&#xff08;我们只会去了解 graphic buffer的创建、input bytebuffer的创建、secure buffer的创…...

力扣题目学习笔记(OC + Swift)21. 合并两个有序链表

21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 链表解题经典三把斧&#xff1a; 哑巴节点栈快慢指针 此题比较容易想到的解法是迭代法&#xff0c;生成哑巴节点&#xff0c;然后迭代生成后续节点。…...

C# WPF上位机开发(windows pad上的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大部分同学可能都认为c# wpf只能用在pc端。其实这是一种误解。c# wpf固然暂时只能运行在windows平台上面&#xff0c;但是windows平台不仅仅是电脑…...

Word使用技巧【开题报告】

1、修改目录&#xff1a;选中目录&#xff0c;点击更新域。 2、更改或删除单个页面上的页眉或页脚 3、借助其他软件在Word导入参考文献 利用zetero导入文献&#xff1a;安装zetero 解决参考文献插入问题 在Word中插入文献操作步骤 英文文献出现“等”&#xff0c;如何解决 Zote…...

电子学会C/C++编程等级考试2022年06月(七级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:有多少种二叉树 输入n(1<n<13),求n个结点的二叉树有多少种形态 时间限制:1000 内存限制:65536输入 整数n输出 答案 样例输入 3样例输出 5 答案: //参考答案 #include<bits/stdc++.h> using namespace std; …...

git中的smart checkout和force checkout

切换分支时出现了这个问题&#xff1a; 这是因为shiyan01分支修改了代码,但是没有commit, 所以在切换到test分支的时候弹出这个窗口 一、smart checkout(智能签出) 会把shiyan01分支的改动内容带到test分支。合并处理后的内容就变成了test分支的内容,而shiyan01分支的改动会被…...

vue3整合Element-Plus,极速上手。

条件分页查询&#xff1a; 需求分析&#xff1a; form表单 Button按钮 Table表格 Pagination分页 页面布局&#xff1a; 搜索表单&#xff1a; 如果表单封装的数据较多&#xff0c;建议绑定到一个对象中。 …...

学习Vue2.x

文章目录 一、使用Vue脚手架1.ref和props属性2.mixin混入3.组件化编码流程4.webStorage5.组件自定义事件6.全局事件总线7.消息订阅与发布 二、使用步骤1.引入库 一、使用Vue脚手架 1.ref和props属性 ref属性&#xff1a; &#xff08;1&#xff09;被用来给元素或子组件注册应…...

新手如何快速熟悉代码,写出东西(持续更新)

目录 第一章、最小编程任务的设想1.1&#xff09;程序员入门会遇到的问题1.2&#xff09;最小编程任务的设想1.3&#xff09;编程逻辑1.4&#xff09;具体需求 第二章、最小编程单元的练习2.1&#xff09;代码/需求方面2.1.1&#xff09;初级练习2.1.2&#xff09;中级练习2.1.…...

11-网络安全框架及模型-软件安全能力成熟度模型(SSCMM)

目录 软件安全能力成熟度模型 1 背景概述 2 主要内容 3 成熟度等级定义 4 关键过程和实践 5 评估方法 6 改进建议 7 持续改进 8 主要价值 9 应用场景 10 优势和局限性 备注 软件安全能力成熟度模型 1 背景概述 SSCMM模型是软件安全能力成熟度模型&#xff0c;它描…...

Linux操作系统基础知识点

Linux是一种计算机操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年首次发布。Linux操作系统通常与GNU套件一起使用&#xff0c;因此也被称为GNU/Linux。它是一种类UNIX的操作系统&#xff0c;设计为多用户、多任务…...

python 通过opencv及face_recognition识别人脸

效果&#xff1a; 使用Python的cv2库和face_recognition库来进行人脸检测和比对的 0是代表一样 认为是同一人。 代码&#xff1a; pip install opencv-python pip install face_recognition# 导入cv2库&#xff0c;用于图像处理 import cv2 # 导入face_recognition库&#…...

Android开发中常见的Hook技术有哪些?

Hook技术介绍 Hook技术是一种在软件开发中常见的技术&#xff0c;它允许开发者在特定的事件发生时插入自定义的代码逻辑。常见的应用场景包括在函数调用前后执行特定的操作&#xff0c;或者在特定的事件发生时触发自定义的处理逻辑。 在Android开发中&#xff0c;Hook通常是通…...

【linux c多线程】线程的创建,线程信息的获取,获取线程返回值

线程创建 ​专栏内容&#xff1a; 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构&#xff0c;以及如何实现多机的数据库节点的多读多写&#xff0c;与传统主备&#xff0c;MPP的区别&#xff0c;技术难点的分析&#xff0c;数据元数据同步&#xff0c;多主节点的情况下对…...

MFC或QT中,自绘控件的目的和实现步骤

MFC自绘控件的步骤 自绘控件的目的是为了能够自定义控件的外观、行为和交互方式&#xff0c;以满足特定的需求&#xff0c;同时增强应用程序的用户体验。 实现步骤如下&#xff1a; 1、创建一个继承自MFC控件基类&#xff08;如CButton、CStatic等&#xff09;的自定义控件类…...

ceph集群搭建详细教程(ceph-deploy)

ceph-deploy比较适合生产环境&#xff0c;不是用cephadm搭建。相对麻烦一些&#xff0c;但是并不难&#xff0c;细节把握好就行&#xff0c;只是命令多一些而已。 实验环境 服务器主机public网段IP&#xff08;对外服务&#xff09;cluster网段IP&#xff08;集群通信&#x…...

机器视觉系统选型-避免畸变

在定位及高精度测量的系统中&#xff0c;镜头畸变的影响尤其重要 • 使用远心镜头 • 进行系统标定...

机器学习笔记 - 线性判别分析(LDA)的原理和应用

一、LDA简述 线性判别分析(LDA)是监督机器学习中用于解决多类分类问题的一种方法。LDA通过数据降维来分离具有多个特征的多个类。这项技术在数据科学中很重要,因为它有助于优化机器学习模型。 线性判别分析,也称为正态判别分析 (NDA) 或判别函数分析 (DFA),遵循生成模型框…...

基于5G智能网关的智慧塔吊监测方案

塔吊是建筑施工中必不可少的设施&#xff0c;由于塔吊工作重心高、起重载荷大、人工视距/视角受限等因素&#xff0c;也使得塔吊在工作过程中着较多的危险因素。对此&#xff0c;可以部署基于工业5G智能网关搭建智慧塔吊安全监测系统&#xff0c;实现对塔吊运行的全局精细监测感…...

CountDownLatch详解以及用法示例

一、什么是CountDownLatch CountDownLatch中count down是倒数的意思&#xff0c;latch则是门闩的含义。整体含义可以理解为倒数的门栓。 CountDownLatch的作用也是如此&#xff0c;在构造CountDownLatch(int count)&#xff1a;的时候需要传入一个整数count&#xff0c;在这个…...

【http】缓存协议

✨ 专栏介绍 在当今互联网时代&#xff0c;计算机网络已经成为了人们生活和工作中不可或缺的一部分。而要实现计算机之间的通信和数据传输&#xff0c;就需要依靠各种网络协议来进行规范和约束。无论是浏览网页、发送电子邮件还是进行在线交流&#xff0c;都离不开各种各样的网…...

vscode中使用GitHub Copilot Chat

文章目录 一、什么是Github Copilot Chat二、安装使用三、如何使用1. 聊天功能2. 内联功能 一、什么是Github Copilot Chat GitHub Copilot Chat 由 OpenAI 的 GPT-4 大型多模态模型提供支持&#xff0c;能带来更准确的代码建议、解释和指导。GitHub Copilot Chat 的内联功能可…...

lvgl 双物理显示器的驱动实现

目录 一、背景 1. 要实现的功能2. lvgl 版本 二、简单粗暴的方式 理论上可以这样实现缺陷&#xff1a; 三、lvgl 自身机制支持 3.1 实现思路3.2 初始化缓冲区和注册显示驱动 3.2.1 复制lv_port_disp → lv_port_disp_23.2.2 修改 lv_port_disp_2 文件3.2.3 在应用层调用显示器…...

论文阅读——X-Decoder

Generalized Decoding for Pixel, Image, and Language Towards a Generalized Multi-Modal Foundation Model 1、概述 X-Decoder没有为视觉和VL任务开发统一的接口&#xff0c;而是建立了一个通用的解码范式&#xff0c;该范式可以通过采用共同的&#xff08;例如语义&#…...

【Kubernetes】控制器Statefulset

Statefulset控制器 一、概念二、Statefulset资源清单文件编写技巧2.1、查看定义Statefulset资源需要的字段2.2、查看statefulset.spec字段如何定义2.3、查看statefulset的spec.template字段如何定义 三、Statefulset使用案例&#xff1a;部署web站点3.1、编写一个Statefulset资…...

智能优化算法应用:基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鱼鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…...