基于GreenDao 进行Android大容量数据对数据库进行增,改,查的处理操作。

前言

我有一个朋友在开发当中接到一个需求,需要对20w+数据进行下载,并将数据进行增,改,查的处理。
下载数据源是一个整合的压缩包,20w+的数据也就几M大小,所以下载不成问题,主要是操作数据库遇到了一些问题。

使用普通的SQL语句操作或者使用GreenDao自带的Api进行操作

// Api插入、增加20w+/1条数据操作
        Query<Person> query = sDaoSession.getPersonDao()
        .queryBuilder()
        .where(PersonDao.Properties.Idcard.eq(person.getIdcard())).build();
        person.setStatus(1);
        person.setSync(1);
        Person resultPerson = query.unique();
        if (resultPerson != null) {
            person.setId(resultPerson.getId());
            sDaoSession.getPersonDao().update(person);
            return;
        }
        sDaoSession.getPersonDao().insert(person);

或者使用Api进行Sql语句进行20w/1条数据操作插入 ,发现数据增加和更新非常缓慢,20w+数据需要1个小时以上才可以完成数据库的增加和更新。

分析原因(查找导致数据插入缓慢的问题所在)

1.通过logcat 控制台输出的日记发现,greendao在进行数据库操作的时候
,以及查看实现源码可得知每一次进行数据库插入都会进行一次
db.beginTransaction()以及db.endTransaction()操作,这里判断也许是造成缓慢的原因之一。
2.通过问题1 所在继续深入源码可得知每一次操作数据库,greendao 都会进行一次
SQLiteStatement rawStmt = (SQLiteStatement) stmt.getRawStatement()。根据我的经验判断,这两个
地方的对象其实是可以重新复用起来的。

解决

1.先上代码:
    public static void insertPersonLock(List<Person> persons) {
        sDaoSession.runInTx(new Runnable() {
            @Override
            public void run() {
                DaoConfig dc = new DaoConfig(sDaoSession.getDatabase(), PersonDao.class);
                DatabaseStatement insertStatement = dc.statements.getInsertStatement();
                String updSql = SqlUtils.createSqlUpdate(dc.tablename, dc.nonPkColumns, new String[]{PersonDao.Properties.Idcard.columnName});
                DatabaseStatement updateStmt = sDaoSession.getDatabase().compileStatement(updSql);
                for (Person person : persons) {
                    sDaoSession.getPersonDao().bindValues(insertStatement, person);
                    try {
                        insertStatement.executeInsert();
                    } catch (SQLiteConstraintException e) {
                        bindValuesUpdPerson(updateStmt, person);
                        updateStmt.bindString(dc.nonPkColumns.length + 1, person.getIdcard());
                        updateStmt.execute();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        });
    }
2.根据上述分析以及查看Api得知GreenDao提供了runInTx(Runnable runable) 
用来给用户免去重复进行db.beginTransaction()以及db.endTransaction()操作  
但是对单条数据依旧还是原来的套路,但是如果我把相对20w+条的N条进行存储
,那么这N条数据进行数据数据库操作的过程中就不用频繁进行
db.beginTransaction()以及db.endTransaction()操作。
那么 DatabaseStatement insertStatement的创建
以及DatabaseStatement updateStmt的创建也是一样的道理。

结果

20w+数据由原来的1小时+变成了10分钟以内。效果显著。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值