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_a
      case 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:注册内容观察者ContentObserver
    getContentResolver().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类进行解除

相关推荐

  1. Android基础基本布局

    2024-07-12 13:06:03       13 阅读
  2. Android 数据库

    2024-07-12 13:06:03       22 阅读
  3. Android : Kotlin 基础 入门

    2024-07-12 13:06:03       59 阅读
  4. Android-JVM基础

    2024-07-12 13:06:03       44 阅读
  5. Android基础知识

    2024-07-12 13:06:03       49 阅读
  6. Android GPS基础原理

    2024-07-12 13:06:03       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 13:06:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 13:06:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 13:06:03       58 阅读
  4. Python语言-面向对象

    2024-07-12 13:06:03       69 阅读

热门阅读

  1. js 移动数组元素的几个方法

    2024-07-12 13:06:03       18 阅读
  2. 使用C# 实现期望最大化算法

    2024-07-12 13:06:03       20 阅读
  3. [NLP Begin] Classical NLP Methods - HMM

    2024-07-12 13:06:03       25 阅读
  4. 【ELK】filebeat 和logstash区别

    2024-07-12 13:06:03       18 阅读
  5. 行为模式9.策略模式------促销活动设计方案

    2024-07-12 13:06:03       21 阅读
  6. Vim 编辑文件时中文乱码的解决方法

    2024-07-12 13:06:03       18 阅读
  7. vim删除多行

    2024-07-12 13:06:03       25 阅读
  8. 嵌入式裸机开发与 Linux 开发

    2024-07-12 13:06:03       22 阅读
  9. 机器学习-分类器-总结

    2024-07-12 13:06:03       19 阅读
  10. Git-如何基于某个tag创建一个新分支

    2024-07-12 13:06:03       27 阅读
  11. 【Linux】Vim 使用教程

    2024-07-12 13:06:03       17 阅读