将具有较少字段的新 POJO 类映射到现有的 Room 表

Che*_*eng 6 sqlite android android-sqlite android-database android-room

目前,我们有以下 Dao 和模型类。

笔记道

@Query("SELECT * FROM note")
public abstract LiveData<List<Note>> getAllNotes();
Run Code Online (Sandbox Code Playgroud)

笔记类

@Entity(
    tableName = "note"
)
public class Note {
    @ColumnInfo(name = "title")
    private String title;

    // Can contain a huge String.
    @ColumnInfo(name = "body")
    private String body;
}
Run Code Online (Sandbox Code Playgroud)

但是,在某些情况下,我们只对加载感兴趣title

一次加载所有Note带有大body字符串的s ,可能会导致OutOfMemoryException

有什么办法,我们可以创建另一个 POJO 如下?

public class SimpleNote {
    private String title;
}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以返回SimpleNotefrom 的列表NoteDao

@Query("???")
public abstract LiveData<List<SimpleNote>> getAllSimpleNotes();
Run Code Online (Sandbox Code Playgroud)

小智 5

这对你有用:

@Query("SELECT title FROM note") 
LiveData<List<String>> getAllNoteTitles();
Run Code Online (Sandbox Code Playgroud)

当您调用 时SELECT *,它将选择表中的所有字段。


azi*_*ian 4

正如“返回列的子集”文档中所示:

大多数时候,您只需要获取实体的几个字段。例如,您的 UI 可能仅显示用户的名字和姓氏,而不是有关用户的所有详细信息。通过仅获取应用程序 UI 中显示的列,您可以节省宝贵的资源,并且查询可以更快地完成。

Room允许您从查询中返回任何基于 Java 的对象,只要结果列集可以映射到返回的对象即可。例如,您可以创建以下基于 Java 的普通旧对象 (POJO) 来获取用户的名字和姓氏:

data class NameTuple(
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)
Run Code Online (Sandbox Code Playgroud)

现在,您可以在查询方法中使用此 POJO:

@Dao
interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    fun loadFullName(): List<NameTuple>
}
Run Code Online (Sandbox Code Playgroud)

Room知道查询返回first_namelast_name列的值,并且这些值可以映射到NameTuple类的字段中。因此,Room可以生成正确的代码。如果查询返回太多列,或者类中不存在列NameTupleRoom会显示警告。


回到你的情况:定义SimpleNote如下:

public class SimpleNote {
    @ColumnInfo(name = "title")
    private String title;
}
Run Code Online (Sandbox Code Playgroud)

然后就可以查询表了:

@Query("SELECT title FROM note")
public abstract LiveData<List<SimpleNote>> getAllSimpleNotes();
Run Code Online (Sandbox Code Playgroud)