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 存储为单个元素,不如将其解析并存储在数据库中的单独列或表中。
这样,
- 您可以在 JSON 中将不需要的数据保存在数据库中。
- 您可以一次查询一部分数据(几列),这样查询的数据不会超过2MB
CursorWindow
限制。
或者你可以试试其他数据库系统,比如Realm(我没试过,所以我不确定那里是否有任何限制)。
我必须执行查询并将结果存储在列表中,我使用的函数如下:
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 存储为单个元素,不如将其解析并存储在数据库中的单独列或表中。
这样,
- 您可以在 JSON 中将不需要的数据保存在数据库中。
- 您可以一次查询一部分数据(几列),这样查询的数据不会超过2MB
CursorWindow
限制。
或者你可以试试其他数据库系统,比如Realm(我没试过,所以我不确定那里是否有任何限制)。