• 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类进行解除
    
  • 相关阅读:
    了解5个区别,FPmarkets用烛台和Renko图实现交易翻倍
    Qt基础教程:QString
    C++ 炼气期之数据是主角
    【MAPBOX基础功能】23、mapbox通过marker的方式绘制波纹点位
    numpy函数总结
    大数据笔记-NIFI(第一篇)
    nginx rewrite参数 以及 $1、$2参数解析(附有生产配置实例)
    卷王杯 easy unserialize
    OpenCV-Python学习(3)—— OpenCV 图像色彩空间转换
    Linux 创建.sh脚本文件
  • 原文地址:https://blog.csdn.net/m0_74837900/article/details/140360019