好久没有写技术文章,明早4点还要爬起来赶飞机,感觉这个坑有必要记录一下,以慰藉一下自己脆弱的灵魂。周一和周二忙了2天的样子才解决这个问题,中间填了不少的坑,反正已经夜深了,慢慢地记录一点。
场景:项目中有块业务中的一张表中大概有60w条的数据,终端拉下来大概有20多万条吧,表中的数据是一棵未知深度的数,如果想知道深度,需要递归。
第一版:将所有数据通过一个接口全部拉下来(接口是采用SOAP的Webservice),随着数据慢慢的丰富,发现一个接口完全无法一次拉取这么多数据。修改....
第二版:将最父级节点用一个接口拉下来,该接口的数据不多,大概也就10多条。然后通过该数据中的主键再调用另外一个接口去获取该节点的子节点。但是发现有个别接口数据量太大,在封装JSON时容易内存溢出,导致app闪退。需要再次改进...
第三版:在第二版的基础上,将获取子节点数据的接口改成获取txt文件的路径,通过文件路径去下载文本文件(程序读文件的速度比较快的),在Java中提供了很好的读写文件的api,而且下载文件的速度要比获取接口的速度要快。所以就采用了这种方案。但是,在一次读文件的过程中,有些比较大的文件读并封装成对象的时候也容易导致内存溢出,而且写入数据库的时候灰常慢(开启事务批量写入)。但是问题依旧没有解决,经过几种编码的测试,最终有了现在算是最优的解决方案。首先解决批量处理问题,记得在学JDBC的时候有个PreparedStatement类,是一个连接数据库预编译、可批处理的Dao层的类。在SQLite中也有一个与这个很类似的类,叫SQLiteStatement,不知道的大家自行补脑。批处理插入卡顿的问题算是初步解决了,但是大文件里的数据该如何处理呢?当然是读字节,每次读x*1024*1024(x<6),大概在这个范围,这还要看手机性能(内存),如果是老古董,那就完蛋了,需要动态设置才行。把每次读的一批数据封装成SQLiteStatement即可,然后执行其批量操作即可。思路讲到这里结束。
2017-04-19 00:23