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);//批量更新
}