SQLite CursorWindow 限制 - 如何避免崩溃

SQLite CursorWindow limit - How to avoid crash

我必须执行查询并将结果存储在列表中,我使用的函数如下:

List<SpoolInDB> getSpoolInRecords(String label, boolean getLastInserted) {
    List<SpoolInDB> spoolInList = new ArrayList<>();
    try {
        if (mdb == null)
            mdb = mdbHelper.getWritableDatabase();

        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(TABLE_SPOOLIN);

        Cursor c = qb.query(mdb, null, " label='" + label + "'", null, null, null, " dateins " + (getLastInserted ? "desc" : "asc"));
        if (c != null) {
            c.moveToFirst();
            if (c.getCount() > 0) {
                int ndxid = c.getColumnIndex("id");
                int ndxserverID = c.getColumnIndex("serverID");
                int ndxlabel = c.getColumnIndex("label");
                int ndxvalue = c.getColumnIndex("value");
                int ndxpriority = c.getColumnIndex("priority");
                int ndxdateins = c.getColumnIndex("dateins");

                do {
                    SpoolInDB spoolIn = new SpoolInDB();
                    spoolIn.setId(c.getString(ndxid));
                    spoolIn.setServerID(c.getString(ndxserverID));
                    spoolIn.setLabel(c.getString(ndxlabel));
                    spoolIn.setValue(c.getString(ndxvalue));
                    spoolIn.setPriority(c.getString(ndxpriority));
                    spoolIn.setDateins(c.getString(ndxdateins));
                    spoolInList.add(spoolIn);

                } while (c.moveToNext());
            }
            c.close();
        }
    } catch (Exception e) {
        wil.WriteFile("4)DbGest - Exception: " + e.toString());
    }
    return spoolInList;
}

在正常情况下,此函数可以完美运行,但在某些情况下,此函数会产生异常:

Window is full: requested allocation 3209815 bytes, free space 2096647 bytes, window size 2097152 bytes

这个问题的发生是因为在 "values" 字段中我可以存储 json 数据,在某些情况下可能大于 2mb,我无法预测数据何时大于 2mb,我需要一个始终有效的解决方案。

我该如何解决我的问题?

CursorWindow 大小限制为 2MB(截至目前)。您无法读取大小超过 2MB 的单个行,因为无法将其放入 Cursor

因此,与其将整个 JSON 存储为单个元素,不如将其解析并存储在数据库中的单独列或表中。

这样,

  1. 您可以在 JSON 中将不需要的数据保存在数据库中。
  2. 您可以一次查询一部分数据(几列),这样查询的数据不会超过2MB CursorWindow限制。

或者你可以试试其他数据库系统,比如Realm(我没试过,所以我不确定那里是否有任何限制)。