需求定义
1,通常需要从数据库里面撸出来一大片数据,一次数据库io会很耗时导致超时,
2,检索出符合条件的数据,但是仅仅依靠数据库里面的记录还无法判定是否符合条件,必须通过外部服务获取相关的信息来判断。
实现思路
如果我们能够将数据库里面的记录做成一个流,那么上面的问题将很容易解决,前者只需要使用limit()就可以获得需要的记录条数,后者加一个filter函数也很容易过滤掉。那么如果将一个远端的数据源里面的数据做成一个流,又不会对数据源造成很大的瞬时压力呢?
最明显的思路是我们需要对数据源里面的数据进行分段检索,当然我们检索的数据肯定是有一个顺序的,满足流的ORDERED属性,这样也不至于重复取出数据,或者遗漏了数据。比如按照primary key的降序取出来。这样分段检索函数只需要(startId, limit)这样一对参数就可以了,当然startId这个参数可以是泛型的,并不需要是整形。有了这个函数,我们就可以每次取出一段数据,外面包装成一个Iterator来返回,而Iterator与Stream之间的互相转换已经有了现成的接口:
StreamSupport.stream(spliteratorUnknownSize(iterator(), (NONNULL|IMMUTABLE|ORDERED)), false);
这样就将远端的一个数据源映射成了一个Stream.
对于Iterator的实现,G家的guava框架已经有了很完善的支持,在没有Stream的日子里,Iterator可是被G家玩的出神入化,大家有兴趣可以看看guava里面的框架库。这里可以继承com.google.common.collect.AbstractIterator来快速实现一个迭代器,只需要实现computeNext接口就可以了,超级方便。