zoukankan      html  css  js  c++  java
  • Android上的事件流操作数据库

         最近在浏览某篇有关事件流的文章时,里面提到了数据的流处理,兴趣来了,就想看看能否在Android端实现一个。

         根据文章的介绍,将每次数据的变更事件,像是插入,删除或者更新等,记为一个不可变的事件,让数据在事件中流淌,而不是对数据库进行破坏性的写入,也就是说,直接读取数据的聚合结果就能获取最好的性能。

         事件流可以完成下面的工作:

    1.获取所有的原始事件,可能需要进行转换,然后将它们加载到一个大型的数据仓库中供分析人员使用;

    2.更新全文搜索索引,使用户可以搜索最新的数据;
    3.更新缓存,使系统可以从快速缓存中读取数据,并保证缓存中的数据是最新的;
    4.通过对事件流进行处理创建一个新的事件流,然后将后者作为另一个系统的输入。
        可能带来的好处如下:
    1.松耦合:数据读写使用不同的数据库模式,读取的数据经由写入的数据转换而来,应用程序不同部分间的耦合度降低了;
    2.读写性能:规范化(写入快)和非规范化(读取快)的争论源于数据读写使用同一个模式的假设,如果数据读写使用不同的数据库模式,读写速度都会得到提升;
    3.扩展性:因为事件流是一种简单的抽象,而且允许开发人员将应用程序分解成流的生产者和消费者,所以容易跨机器并行和扩展;
    4.灵活性:原始事件简单明确,模式迁移不会造成多大影响,而向用户展示数据要复杂得多,但如果有一个转换过程可以实现从原始事件到缓存内容的转换,那么当需要新的用户界面时,只需要使用新的逻辑构建新的缓存;
    5.错误场景:原始事件是不变的事实,如果系统出现问题,那么开发人员总是可以用相同的顺序将事件重放。
     
       如果是这样的设计, 编写查询或者规则来匹配满足特定模式的事件,还要在流上进行全文搜索,在流上事先注册一个查询,当有事件匹配查询时发送通知。
    由此衍生出几个概念:
    1.响应式:主要是将事件流提供给用户界面使用;
    2.变更数据捕获:按照我们熟悉的方式使用数据库,但要将任何插入,更新和删除操作抽取到一个数据变更事件流中。
      初步的实现已经出来了,大概的实现如下:
     
    1.创建数据库和表
          在assets文件夹下创建database.xml文件,里面配置数据库的名字,版本号和数据库的表:
       <?xml version="1.0" encoding="utf-8"?>
          <database>
              <!-- 数据库名称 -->
              <dbname value="zwb.db"></dbname>
    
              <!-- 数据库版本 -->
              <version value="1"></version>
    
              <!-- 数据库表 -->
              <list>
                  <mapping class="com.zwb.args.dbpratice.model.Status"></mapping>
                  <mapping class="com.zwb.args.dbpratice.model.User"></mapping>
              </list>
          </database>

         然后初始化DatabaseCache:

    DatabaseCache cache = DatabaseCache.getInstance(this);

        该操作应该是在Application中声明,因为该动作涉及到数据库和表的创建。

    2.基本使用

       声明一个model类,继承自BaseTable:

                 @Table(table = "status")
                 public class Status extends BaseTable {
                     @Column
                     private String name;
                     @Column
                     private String statusId;
    
                     public void setName(String name) {
                         this.name = name;
                     }
    
                     public String getName() {
                         return name;
                     }
    
                     public void setStatusId(String id) {
                         this.statusId = id;
                     }
    
                     public String getStatusId() {
                         return statusId;
                     }
                 }

         其中,@Table声明的是该model对应的表的名字,@Column声明的是该字段对应的数据库中的类型。如果该字段的类型和数据库中的类型不一致,可以通过@ColumnType来指定类型。

    3.数据插入

     Status status = new Status();
     status.setName("转发");
     status.setStatusId("01");
     InsertEvent insertStatusEvent = new InsertEvent();
     insertStatusEvent.to(Status.class).insert(status);

    4.数据更新

     UpdateEvent updateEvent = new UpdateEvent();
     updateEvent.to(Status.class).where("id", "01").update("name", "你好");

    5.数据查询

    List<Status> statusList = cache.from(Status.class).where("statusId", "01").find();
    这样就是查询Status表中的statusId为01的所有记录。当然,也可以查询所有数据:
    List<Status> statusList = cache.from(Status.class).findAll();

    6.数据读取

    DatabaseCache cache = DatabaseCache.getInstance(this);
    List<Status> statusList =  cache.readFromDb(Status.class);

       该操作应该在Application中执行,然后执行相应的数据插入:

     for(Status status : statusList){
          InsertEvent insertEvent = new InsertEvent();
          insertEvent.to(Status.class).insert(status);
    }
     这样数据就会从数据库转移到事件流中。


    7.数据存储
    DatabaseCache cache = DatabaseCache.getInstance(this);
    cache.insertToDb(Status.class);
     这样就会将和Status有关的数据插入到数据库中。


    8.数据删除
    DeleteEvent deleteEvent = new DeleteEvent();
    deleteEvent.to(Status.class).where("id", "01").delete();
      这样就是删除id为01的数据。
    
      如果是删除某个集合的全部数据,则是:
            List<Status> statuses = new ArrayList<Status>();
            for(int i = 0; i < 10; i++){
                  Status status = new Status();
                  status.setName("你好");
                  status.setId("01");
                  statuses.add(status);
            }
            deleteEvent.to(Status.class).deleteAll(statuses);
      如果是删除表的全部数据:
    deleteEvent.to(Status.class).deleteAll();

          这是目前的实现,后面会有时间讲解一下实现的过程,具体的项目地址放在github上:https://github.com/wenjiang/EventStreamDB,有兴趣可以上去看看,顺便给个星星。


     

     


     


     

     

     

     

     

     

     

       

  • 相关阅读:
    Median Value
    237. Delete Node in a Linked List
    206. Reverse Linked List
    160. Intersection of Two Linked Lists
    83. Remove Duplicates from Sorted List
    21. Merge Two Sorted Lists
    477. Total Hamming Distance
    421. Maximum XOR of Two Numbers in an Array
    397. Integer Replacement
    318. Maximum Product of Word Lengths
  • 原文地址:https://www.cnblogs.com/wenjiang/p/4443093.html
Copyright © 2011-2022 走看看