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,有兴趣可以上去看看,顺便给个星星。


     

     


     


     

     

     

     

     

     

     

       

  • 相关阅读:
    课程设置
    专家答疑:ASP.NET MVC与WebForm的区别
    PHP环境的搭建之利器 – APMServ
    office access vs mysql
    IBM Tivoli Identity Manager 5.1 Basic Implementation
    Windows安全认证是如何进行的?
    landesk桌面管理
    转:HBase在淘宝的应用和优化小结
    Workstation ITbased Security Best Practice Configurations
    Scale Your Applications with Component Load Balancing (cont'd)
  • 原文地址:https://www.cnblogs.com/wenjiang/p/4443093.html
Copyright © 2011-2022 走看看