热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Rxjava2_Flowable_Sqlite_Android数据库访问实例

下面小编就为大家分享一篇Rxjava2_Flowable_Sqlite_Android数据库访问实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

一、使用Rxjava访问数据库的优点:

1.随意的线程控制,数据库操作在一个线程,返回数据处理在ui线程

2.随时订阅和取消订阅,而不必再使用回调函数

3.对读取的数据用rxjava进行过滤,流式处理

4.使用sqlbrite可以原生返回rxjava的格式,同时是响应式数据库框架

(有数据添加和更新时自动调用之前订阅了的读取函数,达到有数据添加自动更新ui的效果,

同时这个特性没有禁止的方法,只能通过取消订阅停止这个功能,对于有的框架这反而是一种累赘)

二、接下来之关注实现过程:

本次实现用rxjava2的Flowable,有被压支持(在不需要被压支持的情况建议使用Observable)

实现一个稳健的的可灵活切换其他数据库的结构,当然是先定义数据库访问接口。然后跟具不同的数据库实现接口的方法

定义接口:(对于update,delete,insert,可以选择void类型,来简化调用代码,但缺少了执行结果判断)

public interface DbSource { 
  //String sql = "insert into table_task (tid,startts) values(tid,startts)"; 
  Flowable insertNewTask(int tid, int startts); 
 
  //String sql = "select * from table_task"; 
  Flowable> getAllTask(); 
 
  //String sql = "select * from table_task where endts = 0"; 
  Flowable> getRunningTask(); 
 
  //String sql = "update table_task set isuploadend=isuploadend where tid=tid"; 
  Flowable markUploadEnd(int tid, boolean isuploadend); 
 
  //String sql = "delete from table_task where tid=tid and endts>0"; 
  Flowable deleteTask(int tid); 
} 

三、用Android原生的Sqlite实现数据库操作

public class SimpleDb implements DbSource { 
 
 private static SimpleDb sqlite; 
 private SqliteHelper sqliteHelper; 
 
 private SimpleDb(Context context) { 
  this.sqliteHelper = new SqliteHelper(context); 
 } 
 
 public static synchronized SimpleDb getInstance(Context context) { 
  if (sqlite == null ) 
   sqlite = new SimpleDb(context); 
  return sqlite; 
 } 
 
 Flowable insertNewTask(int tid, int startts) { 
  return Flowable.create(new FlowableOnSubscribe() { 
   @Override 
   public void subscribe(FlowableEmitter e) throws Exception { 
    //这里数据库操作只做示例代码,主要关注rxjava的Flowable使用方法 
    ContentValues values = new ContentValues(); 
    values.put(“tid”, 1); 
    values.put(“startts”,13233); 
    if(sqliteHelper.getWriteableDatabase().insert(TABLE_NAME, null, values) != -1) 
     e.onNext(true); 
    else 
     e.onNext(false); 
    e.onComplete(); 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
 
 Flowable> getAllTask() { 
  return Flowable.create(new FlowableOnSubscribe>() { 
   @Override 
   public void subscribe(FlowableEmitter> e) throws Exception { 
 
    List taskList = new ArrayList<>(); 
    StringBuilder sql = new StringBuilder(100); 
    sql.append("select * from "); 
    sql.append(SqliteHelper.TABLE_NAME_TASK); 
 
    SQLiteDatabase sqLiteDatabase = sqliteHelper.getReadableDatabase(); 
    Cursor cursor = sqLiteDatabase.rawQuery(sql.toString(), null); 
    if (cursor.moveToFirst()) { 
     int count = cursor.getCount(); 
     for (int a = 0; a > getRunningTask() { 
  return Flowable.create(new FlowableOnSubscribe>() { 
   @Override 
   public void subscribe(FlowableEmitter> e) throws Exception { 
    TaskItem item = null; 
    StringBuilder sql = new StringBuilder(100); 
    sql.append("select * from "); 
    sql.append(SqliteHelper.TABLE_NAME_TASK); 
    sql.append(" where endts=0 limit 1"); 
    SQLiteDatabase sqLiteDatabase = sqliteHelper.getReadableDatabase(); 
    Cursor cursor = sqLiteDatabase.rawQuery(sql.toString(), null); 
    if (cursor.moveToFirst()) { 
     int count = cursor.getCount(); 
     if (count == 1) { 
      item = new TaskItem(); 
      item.setId(cursor.getInt(0)); 
      item.setTid(cursor.getInt(1)); 
      item.setStartts(cursor.getInt(2)); 
      item.setEndts(cursor.getInt(3)); 
     } 
    } 
    cursor.close(); 
    sqLiteDatabase.close(); 
 
    e.onNext(Optional.fromNullable(item)); //import com.google.common.base.Optional;//安全检查,待会看调用的代码,配合rxjava很好 
    e.onComplete(); 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
  
 Flowable markUploadEnd(int tid, boolean isuploadend) { 
   return Flowable.create(new FlowableOnSubscribe() { 
   @Override 
   public void subscribe(FlowableEmitter e) throws Exception { 
    //这里数据库操作只做示例代码,主要关注rxjava的Flowable使用方法 
    //数据库操作代码 
    e.onNext(false);//返回结果 
    e.onComplete();//返回结束 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
 
   
 Flowable deleteTask(int tid) { 
  return Flowable.create(new FlowableOnSubscribe() { 
   @Override 
   public void subscribe(FlowableEmitter e) throws Exception { 
    //这里数据库操作只做示例代码,主要关注rxjava的Flowable使用方法 
    //数据库操作代码 
    e.onNext(false);//返回结果 
    e.onComplete();//返回结束 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
} 

四、同一个接口使用sqlbrite的实现方式

public class BriteDb implements DbSource { 
 @NonNull 
 protected final BriteDatabase mDatabaseHelper; 
 @NonNull 
 private Function mTaskMapperFunction; 
 @NonNull 
 private Function mPoiMapperFunction; 
 @NonNull 
 private Function mInterestPoiMapperFunction; 
 // Prevent direct instantiation. 
 private BriteDb(@NonNull Context context) { 
  DbHelper dbHelper = new DbHelper(context); 
  SqlBrite sqlBrite = new SqlBrite.Builder().build(); 
  mDatabaseHelper = sqlBrite.wrapDatabaseHelper(dbHelper, Schedulers.io(); 
  mTaskMapperFunction = this::getTask; 
  mPoiMapperFunction = this::getPoi; 
  mInterestPoiMapperFunction = this::getInterestPoi; 
 } 
 
 @Nullable 
 private static BriteDb INSTANCE; 
 public static BriteDb getInstance(@NonNull Context context) { 
  if (INSTANCE == null) { 
   INSTANCE = new BriteDb(context); 
  } 
  return INSTANCE; 
 } 
 
 @NonNull 
 private TaskItem getTask(@NonNull Cursor c) { 
  TaskItem item = new TaskItem(); 
  item.setId(c.getInt(c.getColumnIndexOrThrow(PersistenceContract.TaskEntry.COLUMN_TASK_ID))); 
  item.setTid(c.getInt(c.getColumnIndexOrThrow(PersistenceContract.TaskEntry.COLUMN_TASK_TID))); 
  item.setStartts(c.getInt(c.getColumnIndexOrThrow(PersistenceContract.TaskEntry.COLUMN_TASK_STARTTS))); 
  item.setEndts(c.getInt(c.getColumnIndexOrThrow(PersistenceContract.TaskEntry.COLUMN_TASK_ENDTS))); 
  return item; 
 } 
  
 @Override 
 public void insertNewTask(int tid, int startts) { 
  ContentValues values = new ContentValues(); 
  values.put(PersistenceContract.TaskEntry.COLUMN_TASK_TID, tid); 
  values.put(PersistenceContract.TaskEntry.COLUMN_TASK_STARTTS, startts); 
  mDatabaseHelper.insert(PersistenceContract.TaskEntry.TABLE_NAME_TASK, values, SQLiteDatabase.CONFLICT_REPLACE); 
 } 
 
 @Override 
 public Flowable> getAllTask() { 
  String sql = String.format("SELECT * FROM %s", PersistenceContract.TaskEntry.TABLE_NAME_TASK);//TABLE_NAME_TASK表的名字字符串 
  return mDatabaseHelper.createQuery(PersistenceContract.TaskEntry.TABLE_NAME_TASK, sql) 
    .mapToList(mTaskMapperFunction) 
    .toFlowable(BackpressureStrategy.BUFFER); 
 } 
 
 @Override 
 public Flowable> getRunningTask() { 
  String sql = String.format("SELECT * FROM %s WHERE %s = &#63; limit 1", 
    PersistenceContract.TaskEntry.TABLE_NAME_TASK, PersistenceContract.TaskEntry.COLUMN_TASK_ENDTS); 
  return mDatabaseHelper.createQuery(PersistenceContract.TaskEntry.TABLE_NAME_TASK, sql, "0") 
    .mapToOne(cursor -> Optional.fromNullable(mTaskMapperFunction.apply(cursor))) 
    .toFlowable(BackpressureStrategy.BUFFER); 
 } 
 
 @Override 
 public Flowable markUploadEnd(int tid, boolean isuploadend) { 
  return Flowable.create(new FlowableOnSubscribe() { 
   @Override 
   public void subscribe(FlowableEmitter e) throws Exception { 
     ContentValues values = new ContentValues(); 
     if(isuploadend) { 
      values.put(PersistenceContract.TaskEntry.COLUMN_TASK_ISUPLOADEND, 1); 
     } else { 
      values.put(PersistenceContract.TaskEntry.COLUMN_TASK_ISUPLOADEND, 0); 
     } 
     String selection = PersistenceContract.TaskEntry.COLUMN_TASK_TID + " = &#63;"; 
     //String[] selectiOnArgs= {String.valueOf(tid)}; 
     String selectiOnArgs= String.valueOf(tid); 
     int res = mDatabaseHelper.update(PersistenceContract.TaskEntry.TABLE_NAME_TASK, values, selection, selectionArgs); 
     if (res > 0) { 
      e.onNext(true);//返回结果 
     } else { 
       e.onNext(false);//返回结果 
     } 
     e.onComplete();//返回结束 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
 
 @Override 
 public Flowable deleteTask(int tid) { 
  return Flowable.create(new FlowableOnSubscribe() { 
   @Override 
   public void subscribe(FlowableEmitter e) throws Exception { 
     String selection = PersistenceContract.TaskEntry.COLUMN_TASK_TID + " = &#63; AND "+ 
             PersistenceContract.TaskEntry.COLUMN_TASK_ENDTS + " > 0"; 
     String[] selectiOnArgs= new String[1]; 
     selectionArgs[0] = String.valueOf(tid); 
     int res = mDatabaseHelper.delete(PersistenceContract.TaskEntry.TABLE_NAME_TASK, selection, selectionArgs); 
     if (res > 0) { 
      e.onNext(true);//返回结果 
     } else { 
       e.onNext(false);//返回结果 
     } 
     e.onComplete();//返回结束 
   } 
  }, BackpressureStrategy.BUFFER); 
 } 
} 

五、数据库调用使用方法

使用了lambda简化了表达式进一步简化代码:

简化方法:在/app/build.gradle里面加入如下内容:(defaultConfig的外面)

compileOptions { 
 sourceCompatibility JavaVersion.VERSION_1_8 
 targetCompatibility JavaVersion.VERSION_1_8 
} 

接口调用(获得数据库实例):

//全局定义的实例获取类,以后想要换数据库,只需在这个类里切换即可 
public class Injection { 
 public static DbSource getDbSource(Context context) { 
  //choose one of them 
  //return BriteDb.getInstance(context); 
  return SimpleDb.getInstance(context); 
 } 
} 
 
DbSource db = Injection.getInstance(mContext); 
 
disposable1 = db.getAllTask() 
       .flatMap(Flowable::fromIterable) 
       .filter(task -> {     //自定义过滤 
         if (!task.getIsuploadend()) { 
          return true; 
         } else { 
          return false; 
         } 
       }) 
       .subscribe(taskItems -> //这里是使用了lambda简化了表达式 
        doTaskProcess(taskItems) 
       , throwable -> { 
        throwable.printStackTrace(); 
       },// onCompleted 
       () -> { 
        if (disposable1 != null && !disposable1.isDisposed()) { 
         disposable1.dispose(); 
        } 
       }); 
 
 disposable1 = db.getRunningTask() 
    .filter(Optional::isPresent) //判断是否为空,为空的就跳过 
    .map(Optional::get)    //获取到真的参数 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(taskItem -> {     //onNext() 
       //has running task 
       mTid = taskItem.getTid(); 
    }, throwable -> throwable.printStackTrace() //onError() 
    , () -> disposable1.dispose());    //onComplete() 
 
disposable1 = db.markUploadEnd(tid, isuploadend) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(status -> {     //onNext() 
       if (status) { 
        //dosomething 
       } 
    }, throwable -> throwable.printStackTrace() //onError() 
    , () -> disposable1.dispose());    //onComplete() 
 
disposable1 = db.deleteTask(tid) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(status -> {     //onNext() 
       if (status) { 
        //dosomething 
       } 
    }, throwable -> throwable.printStackTrace() //onError() 
    , () -> disposable1.dispose());    //onComplete() 

以上这篇Rxjava2_Flowable_Sqlite_Android数据库访问实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了adg架构设置在企业数据治理中的应用。随着信息技术的发展,企业IT系统的快速发展使得数据成为企业业务增长的新动力,但同时也带来了数据冗余、数据难发现、效率低下、资源消耗等问题。本文讨论了企业面临的几类尖锐问题,并提出了解决方案,包括确保库表结构与系统测试版本一致、避免数据冗余、快速定位问题等。此外,本文还探讨了adg架构在大版本升级、上云服务和微服务治理方面的应用。通过本文的介绍,读者可以了解到adg架构设置的重要性及其在企业数据治理中的应用。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
author-avatar
mobiledu2402852357
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有