Android数据库基础

目录

1、安卓数据存储方式

2、数据库事务

数据库事务的特性(ACID)

事务的隔离级别

事务总结

3、ContetProvider

作用

​编辑

统一资源标识符URI

​编辑

MIME类型

ContentProvider主要方法

4、ContentResolver

作用

主要方法

使用案例

辅助工具类

ContentUris

UriMatcher

ContentObserver


1、安卓数据存储方式

  • SharedPreference
  • 文件存储
  • SQLite
  • 网络存储

2、数据库事务

数据库事务的特性(ACID)

  • 原子性:事务包含所有操作要么全部成功,要不回滚到原状态
  • 一致性:事务执行前后,数据库的状态保持一致
  • 隔离性:多用户并发访问数据库,多事务间相互不影响
  • 持久性:事务一旦被提交,则永久修改数据库的数据

事务的隔离级别

  • 读未提交
  • 读已提交:避免脏读(读到未提交数据)
  • 可重复度:避免不可重复读(当前事务而言,即使被另一个事务修改源数据,其看到的数据仍然是事务开始时刻的状态)
  • 串行化:避免幻读(一个事务已经开始并且读取了数据之后,另一个事务插入了新的记录,使得第一个事务在后续的操作中可能会看到之前未读到的新数据。)

事务总结

3、ContetProvider

作用

  • 原理底层是采用Binder机制
  • 为存储和获取数据提供统一接口,实现应用程序间数据共享
  • 通过URI可操作不同ContentProvider中数据
  • 外部进程可通过ContentResolver类与ContentProvider进行交互

  • 进程间数据交互与共享,实现跨进程通信
  • ContentProvider相当于搬运工,真正数据源还是数据库、文件、XML、网络

统一资源标识符URI

唯一标识ContentProvider中数据

MIME类型

指定某个扩展名文件用某种应用打开

MIME类型组成 = 类型+子类型

如:

  • text/html
  • text/xml
  • text/css
  • application/pdf

MIME类型形式

ContentProvider主要方法

//外部进程向ContentProvider中添加数据
fun insert(uri:Uri,contentValues values):Uri
//外部进程删除ContentProvider中数据
fun delete(uri:Uri,selection:String,selectionArgs:String[]):Int
//外部进程更新ContentProvider中数据
fun update(uri:Uri,values:ContentValues,selection:String,selectionArgs:String[]):int
//外部应用获取ContentProvider中数据
fun query (uri:Uri,projection:String[],selection:String,selectionArgs:String[],sortOrder:String):Cursor

4、ContentResolver

作用

通过 URI 即可操作不同 ContentProvider中数据

外部进程通过ContentResolver与ContentProvider进行交互

对所有的ContentProvider进行统一管理

主要方法

ContentResolver 类提供了与ContentProvider类相同名字 & 作用的4个方法

//外部进程向ContentProvider中添加数据
fun insert(uri:Uri,contentValues values):Uri
//外部进程删除ContentProvider中数据
fun delete(uri:Uri,selection:String,selectionArgs:String[]):Int
//外部进程更新ContentProvider中数据
fun update(uri:Uri,values:ContentValues,selection:String,selectionArgs:String[]):int
//外部应用获取ContentProvider中数据
fun query (uri:Uri,projection:String[],selection:String,selectionArgs:String[],sortOrder:String):Cursor

使用案例

val resolver = getContentResolver()
val uri = Uri.parse("content://cn.scu.myprovider/user")val cursor:Cursor = resolver.query(uri,null,null,null,"userid desc")

辅助工具类

ContentUris

向URI追加&获取ID

// withAppendedId()作用:向URI追加一个id
Uri uri = Uri.parse("content://cn.scu.myprovider/user") 
Uri resultUri = ContentUris.withAppendedId(uri, 7);  
// 最终生成后的Uri为:content://cn.scu.myprovider/user/7// parseId()作用:从URL中获取ID
Uri uri = Uri.parse("content://cn.scu.myprovider/user/7") 
long personid = ContentUris.parseId(uri); 
//获取的结果为:7

UriMatcher

在ContentProvider中注册URI,根据URI返回注册码,匹配ContentProvider中对应的数据表

// 步骤1:初始化UriMatcher对象UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); //常量UriMatcher.NO_MATCH  = 不匹配任何路径的返回码// 即初始化时不匹配任何东西// 步骤2:在ContentProvider 中注册URI(addURI())int URI_CODE_a = 1;int URI_CODE_b = 2;matcher.addURI("cn.scu.myprovider", "user1", URI_CODE_a); matcher.addURI("cn.scu.myprovider", "user2", URI_CODE_b); // 若URI资源路径 = content://cn.scu.myprovider/user1 ,则返回注册码URI_CODE_a// 若URI资源路径 = content://cn.scu.myprovider/user2 ,则返回注册码URI_CODE_b// 步骤3:根据URI 匹配 URI_CODE,从而匹配ContentProvider中相应的资源(match())@Override   public String getType(Uri uri) {   Uri uri = Uri.parse(" content://cn.scu.myprovider/user1");   switch(matcher.match(uri)){   // 根据URI匹配的返回码是URI_CODE_a// 即matcher.match(uri) == URI_CODE_acase URI_CODE_a:   return tableNameUser1;   // 如果根据URI匹配的返回码是URI_CODE_a,则返回ContentProvider中的名为tableNameUser1的表case URI_CODE_b:   return tableNameUser2;// 如果根据URI匹配的返回码是URI_CODE_b,则返回ContentProvider中的名为tableNameUser2的表}   
}

ContentObserver

观察URI引起ContentProvider中的数据变化&通知访问者

// 步骤1:注册内容观察者ContentObservergetContentResolver().registerContentObserver(uri);// 通过ContentResolver类进行注册,并指定需要观察的URI// 步骤2:当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)public class UserContentProvider extends ContentProvider { public Uri insert(Uri uri, ContentValues values) { db.insert("user", "userid", values); getContext().getContentResolver().notifyChange(uri, null); // 通知访问者} 
}// 步骤3:解除观察者getContentResolver().unregisterContentObserver(uri);// 同样需要通过ContentResolver类进行解除

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

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

相关文章

BPMN.js学习

查看流程图 processView: {title: ,open: false,index: undefined,xmlData:"", },<el-table-column label"模型名称" align"center" :show-overflow-tooltip"true"><template slot-scope"scope"><el-button…

抖音短视频矩阵系统源码开发与部署全解析

1. 需求分析与功能规划 在着手开发短视频矩阵源码之初&#xff0c;首要任务是界定项目需求。这包含对视频上传、编辑、分享、评论及点赞等功能的实现预期。同时&#xff0c;需深入理解目标用户群体的具体需求和使用习惯&#xff0c;以确保产品能够满足市场需求。 2. 技术选型…

游戏如何应对黑灰产工作室

游戏黑灰产工作室&#xff0c;是指以非法渠道、非法手段通过游戏进行牟利的团伙。使用脚本、外挂是黑灰产工作室的显著特征&#xff0c;其常见的牟利方式有&#xff1a;打金工作室、资源囤积号、初始号、自抽号、代练工作室以及营销欺诈等。 ▲ 常见的游戏黑灰产工作室牟利路径…

视频太大怎么压缩变小?这几种压缩方法值得收藏!

视频太大怎么压缩变小&#xff1f;在数字化浪潮汹涌的时代&#xff0c;处理大型视频文件已不再仅仅是存储空间的挑战&#xff0c;我们身处于数据洪流之中&#xff0c;数据的安全与隐私的保护已然成为了我们不得不面对的重大议题&#xff0c;特别是随着视频内容的井喷式增长及其…

音视频开发——FFmpeg 实现MP4转FLV文件 C语言实现

文章目录 转换步骤关键代码完整代码 转换步骤 初始化FFmpeg库打开输入文件找到输入文件的流信息打开输出文件并设置输出格式创建输出文件的流初始化解码器和编码器读取输入文件的帧并写入输出文件释放资源 关键代码 1 初始化FFmpeg库&#xff1a; av_register_all();打开输…

Qt学生管理系统(付源码)

Qt学生管理系统 一、前言1.1 项目介绍1.2 项目目标 2、需求说明2.1 功能性说明2.2 非功能性说明 三、UX设计3.1 登录界面3.2 学生数据展示3.3 信息插入和更新 三、架构说明3.1 客户端结构如下3.2 数据流程图3.2.1 数据管理3.2.2 管理员登录 四、 设计说明3.1 数据库设计3.2 结构…

EdgeOne安全能力开箱测评挑战赛

活动地址&#xff1a;EdgeOne安全能力开箱测评挑战赛-腾讯云开发者社区-腾讯云 随着网络攻击日益频繁&#xff0c;企业网站面临着数据泄露、DDoS攻击、CC攻击等多种安全威胁。如何有效保护企业网站安全&#xff0c;成为企业IT部门的重要任务。腾讯云EdgeOne作为一款集成了CDN和…

智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成

日前&#xff0c;乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序&#xff0c;即可轻松设计符合 Matter 标准的产品。不仅如此&#xff0c;开发者还可以在短短…

算法模块导学

算法分析版本迭代流程图设计算法实践 练就扎实的基本功&#xff0c;可量化&#xff0c;可评估的&#xff0c;不是停留在大脑中的感觉。 1、算法&测开之缘 我们学习算法的目标是为了测试服务的&#xff0c;所以我们要了解测开最终要具备什么样的能力。 测开需要具备的能力…

从0开始的STM32HAL库学习4

对射式红外传感器计数复现 配置工程 我们直接复制oled的工程&#xff0c;但是要重命名。 将PB14设置为中断引脚 自定义命名为sensorcount 设置为上升沿触发 打开中断 配置NVCI 都为默认就可以了 修改代码 修改stm32f1xx_it.c 文件 找到中断函数并修改 void EXTI15_10_I…

Qt:14.容器类控件(QGroupBox、QTabWidget-创建选项卡式界面的控件)

目录 一、QGroupBox&#xff1a; 1.1QGroupBox介绍&#xff1a; 1.2 属性介绍&#xff1a; 二、QTabWidget-创建选项卡式界面的控件&#xff1a; 2.1 QTabWidget介绍&#xff1a; 2.2 属性介绍&#xff1a; 一、QGroupBox&#xff1a; 1.1QGroupBox介绍&#xff1a; QGro…

操作系统安全保护

操作系统安全概述 操作系统&#xff08;Operating System, OS&#xff09;是计算机系统的核心软件&#xff0c;管理硬件资源&#xff0c;提供基本服务&#xff0c;支持应用程序运行。操作系统安全是确保OS及其管理的资源免受未经授权访问、使用、修改和破坏的重要过程。操作系…

Python精神病算法和自我认知异类数学模型

&#x1f3af;要点 &#x1f3af;空间不确定性和动态相互作用自我认知异类模型 | &#x1f3af;精神病神经元算法推理 | &#x1f3af;集体信念催化个人行动力数学模型 | &#x1f3af;物种基因进化关系网络算法 | &#x1f3af;电路噪声低功耗容错解码算法 &#x1f4dc;和-…

【Java】零散知识--感觉每条都有知识在进入脑子唤起回忆

1&#xff0c;什么是双亲委派 AppClassLoader在加载类时&#xff0c;会向上委派&#xff0c;取查找缓存。 AppClassLoader >>ExtClassLoader >>BootStrapClassLoader 情况一 向上委派时查找到了&#xff0c;直接返回。 情况二 当委派到顶层之后&#xff0c;缓…

CSS特效:pointer-events: none;的一种特殊应用

一、需求描述 今天看到一个设计需求&#xff1a;需要在弹框中显示如下界面&#xff0c;其中有两个效果&#xff1a; 1.顶部点击项目&#xff0c;下面的内容能相应滚动定位&#xff0c;同时滚动的时候顶部项目也能相应激活显示 2.顶部右侧有一个模糊渐变效果&#xff0c;并且要…

从0到1搭建数据中台(1)

初识 数据仓库&#xff0c;数据湖&#xff0c;大数据平台&#xff0c;数据中台的发展历程梳理&#xff1b;数据中台的搭建方法论&#xff1b;数据中台搭建的初步落地&#xff0c;参考大神郭忆的课程&#xff0c;看完就会对全貌有个理解。 Easydata大数据生产力平台架构图。 有…

html页面实现socket.io

使用CDN&#xff1a;https://socket.io/zh-CN/docs/v4/client-installation/ socket.on 监听服务端的事件 socket.emit 是客户端的事件 <!DOCTYPE html> <html> <head><title>长时间任务</title><script src"https://cdnjs.cloudflare…

linux 文件末尾追加内容

1、echo echo "Hello, World!" >> example.txt 2、printf printf "Hello, World!\n" >> example.txt 3、cat 多行添加 cat >> example.txt <<EOF Line 1 Line 2 Line 3 EOF 4、sed sed -i ‘$a\要添加的文本’ example.txt 其中…

vue实例和容器的一夫一制——04

//准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp2> <h1>{{name}}</h1> </div> <script> // 验…

【通信协议-RTCM】GPS卫星星历 ---- 对应RTCM十六进制 编码ID(3FB)

注释&#xff1a; RTCM响应消息1014-1017为网络辅助站数据消息的内容&#xff0c;应该不是很重要&#xff08;工作中也未接触到此些语句&#xff09;&#xff0c;故忽略 1. 1019型消息的内容&#xff0c;GPS卫星星历数据 2. 1008型消息的内容——天线描述符和序列号 DATA FI…