GreenDao数据增量更新

GreenDao完美解决数据库数据增量更新功能

问题:开发的程序有离线功能,客户信息要保存到本地数据库,客户的数据每天都会有更新,不可能每天去全量下载更新数据,只能根据最后一次数据的更新时间戳 去下载更新时间戳后面更新的数据,进行数据的增量更新;

GreenDao管理数据库的问题,主键只能是Long类型数据,用户数据后台的id是String类型,不可取为我的主键,计划根据人员的 身份证号 进行数据唯一性确定 进行数据的更新;

先给出增量更新的结果代码:

BufferedReader buffer= FileUtils.getBufferedReaderByPath(absolutePath);
Type listType4 = new TypeToken<List<SeamanCertBeanA>>() {
}.getType();

List<SeamanCertBeanA> seamanCertBeanAList = new GsonBuilder().setLenient().create().fromJson(buffer, listType4);
List<SeamanCertBean> seamanCertBeans = new ArrayList<>();
for (SeamanCertBeanA e : seamanCertBeanAList) {
//为了压缩下载数据体积,后台传来的属性是a,b,c,d这些字段,我需要转换为id ,name,sfzhm等这些属性数据保存本地数据库
    seamanCertBeans.add(e.clone());
}
if (seamanCertBeans.size() > 0) {
    SeamanCertBeanDao seamanCertBeanDao = daoSession.getSeamanCertBeanDao();
    if (url.equals(config.getURL_SHIP_SEANMEN())) {//第一次信息下载,全量导入数据库数据
        seamanCertBeanDao.deleteAll();
        seamanCertBeanDao.insertOrReplaceInTx(seamanCertBeans);
    } else {//信息更新下载,数据增量更新

        List<List<String>> lists = new ArrayList<>();// 身份证集合 的集合

//身份证集合,500一份 (原因是一次插入条数限制500,参数最多999个)
        List<String> sfzhmList = new ArrayList<>();  

        for (int i = 0; i < seamanCertBeans.size(); i++) {
            sfzhmList.add(seamanCertBeans.get(i).getSfzhm());
            if ((i + 1) % 500 == 0 || (i + 1) == seamanCertBeans.size()) {
//500的整数 或者是最后一条数据  保存并更新sfzhmList 
                lists.add(sfzhmList);
               // sfzhmList.clear();
                sfzhmList = new ArrayList<>();
            }
        }


        if(lists.size()>0){
            for (List<String> listSfzhm:lists){
                try {
//根据条件,删除本地旧数据500一批 删除
                    seamanCertBeanDao.queryBuilder().where(SeamanCertBeanDao.Properties.Sfzhm.in(listSfzhm))
                            .buildDelete().executeDeleteWithoutDetachingEntities();
                } catch (Exception e) {
                    e.toString();
                }
            }
        }

//最新的数据批量插入数据库
        seamanCertBeanDao.insertInTx(seamanCertBeans);
//通知数据更新成功
        EventBus.getDefault().post(new MsgEvent(1105, MsgEvent.UPDATE_LOCATION_SUCCESS, "船员信息更新成功"));
    }
//保存最新数据更新的时间戳
    SPUtils.init().putString(SPUtils.UPDATE_SEAMEN_INFO_TIME + userId, time + "");
}

上面是目前我想出的最好的方法了,有高手有更好的方案还请指点一下。。。 

之前代码只适合小批量的操作,由于List<SeamanCertBean> beansInDatabase = seamanCertBeanDao.queryBuilder() .where(SeamanCertBeanDao.Properties.Sfzhm.eq(e.getSfzhm())).list();此项代码频繁的查询数据库,造成数据操作很慢,40M的数据要操作2个多小时才能全部更新完成,代码如下:

List<SeamanCertBean> beansInsert = new ArrayList<>();//需要批量插入的数据
List<SeamanCertBean> beansUpdate = new ArrayList<>();//需要批量更新的数据
List<SeamanCertBean> beansDelete = new ArrayList<>();//需要批量删除的数据
daoSession.runInTx(new Runnable() {
    @Override
    public void run() {
        for (SeamanCertBean e : seamanCertBeans) {//遍历增量数据源
            List<SeamanCertBean> beansInDatabase = seamanCertBeanDao.queryBuilder()
                    .where(SeamanCertBeanDao.Properties.Sfzhm.eq(e.getSfzhm())).list();
            if (beansInDatabase.size() > 0) {//本地数据库有该调数据
                for (int j = 0; j < beansInDatabase.size(); j++) {
                    if (j == 0) {
                        e.setId(beansInDatabase.get(0).getId());
                        beansUpdate.add(e);//第一个把Long类型id赋值给条数据,便于批量updateInTx更新
                    } else {
                        beansDelete.add(beansInDatabase.get(j));//多余记录批量删除集合
                    }
                }
            } else {
                beansInsert.add(e);//没有此数据记录,批量插入集合
            }
        }
    }
});
if (beansDelete.size() > 0) {
    seamanCertBeanDao.deleteInTx(beansDelete);//批量删除
}
if (beansInsert.size() > 0) {
    seamanCertBeanDao.insertInTx(beansInsert);//批量插入
}
if (beansUpdate.size() > 0) {
    seamanCertBeanDao.updateInTx(beansUpdate);//批量更新
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值