【发布时间】:2019-09-06 16:14:06
【问题描述】:
目前,我们有以下数据库表
@Entity(
tableName = "note"
)
public class Note {
@ColumnInfo(name = "body")
private String body;
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
正文字符串的长度,可以是0到一个很大的数字。
在某些情况下,我们需要
- 将所有笔记加载到内存中。
-
LiveData能够通知观察者,如果 SQLitenote表中有任何更改。 - 我们只需要
body的前256 个字符。我们不需要完整的body。为 all 笔记加载整个body字符串可能会导致OutOfMemoryException。
我们有以下 Room Database Dao
@Dao
public abstract class NoteDao {
@Query("SELECT * FROM note")
public abstract LiveData<List<Note>> getAllNotes();
}
getAllNotes 能够满足要求 (1) 和 (2),但不能满足 (3)。
以下getAllNotesWithShortBody 是一个失败的解决方案。
@Dao
public abstract class NoteDao {
@Query("SELECT * FROM note")
public abstract LiveData<List<Note>> getAllNotes();
@Query("SELECT * FROM note")
public abstract List<Note> getAllNotesSync();
public LiveData<List<Note>> getAllNotesWithShortBody() {
MutableLiveData<List<Note>> notesLiveData = new MutableLiveData<>();
//
// Problem 1: Still can cause OutOfMemoryException by loading
// List of notes with complete body string.
//
List<Note> notes = getAllNotesSync();
for (Note note : notes) {
String body = note.getBody();
// Extract first 256 characters from body string.
body = body.substring(0, Math.min(body.length(), 256));
note.setBody(body);
}
notesLiveData.postValue(notes);
//
// Problem 2: The returned LiveData unable to inform observers,
// if there's any changes made in the SQLite `note` table.
//
return notesLiveData;
}
}
我想知道,有没有办法告诉Room database Dao:在以LiveData返回Notes列表之前,请对每个Note的正文列进行转换,将字符串修剪为最多256个字符? em>
查看 Room Dao 生成的源代码
如果我们看一下 Room Dao 生成的源代码
@Override
public LiveData<List<Note>> getAllNotes() {
final String _sql = "SELECT * FROM note";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
...
...
final String _tmpBody;
_tmpBody = _cursor.getString(_cursorIndexOfBody);
_tmpPlainNote.setBody(_tmpBody);
如果有办法在运行时提供转换功能,那就太好了,这样我们就可以拥有
final String _tmpBody;
_tmpBody = transform_function(_cursor.getString(_cursorIndexOfBody));
_tmpPlainNote.setBody(_tmpBody);
p/s 目前请不要反推荐 Paging 库,因为我们的某些功能需要内存中的整个笔记列表(带有修剪的正文字符串)。
【问题讨论】:
-
Sqlite 确实有一个
substr函数。我想你可以试试See this .. 我不确定它是如何处理溢出长度的。 -
棘手的是,如何在 Room Dao 中使用
substr并将其作为 LiveData 返回? -
@Query("SELECT substr(body,1,256) FROM note")
标签: android android-room