如何填充房间库中实体的非列字段

Kev*_*van 16 java sqlite android android-room android-architecture-components

我有一个类实体如下

@Entity
public class Task {    
    private String name; 
    private Integer ParentId;
    private Integer userId;   
    @Ignore
    private int noOfSubTask;
}
Run Code Online (Sandbox Code Playgroud)

在DAO类中有一个方法getTaskList()

@Dao
public interface TaskDao extends Dao<Task> {

@Query("SELECT *,(SELECT count(*) FROM Task b  WHERE a._id = b.ParentId ) AS noOfSubTask FROM Task a ")
LiveData<List<Task>> getTaskList();
}
Run Code Online (Sandbox Code Playgroud)

我想用noOfSubTask填充由(SELECT count(*)FROM Task b WHERE a._id = b.ParentId)部分查询给出的数字,但问题是它不是一列,所以房间库不会映射它getTaskList方法in dao实现(自动生成)类.

有没有办法用dao类房间库的任何方法来填充实体的非列字段(比如我的情况下的noOfSubTask)?

mts*_*kis 7

几天前我遇到了同样的问题,并查看了这个线程。我正在使用Kotlin data类来创建数据库实体。鉴于Kotlin数据类不能很好地与继承子类配合使用,因此不是一个可行的选择。我的解决方案是@Embedded在包装类中使用关键字,如下所示:

data class TaskToDisplay(@Embedded
                         var task: Task,
                         var noOfSubTask: Int = 0)
Run Code Online (Sandbox Code Playgroud)

此解决方案不会在数据库中创建其他列,最重要的是,将所有“任务”字段与“房间”的响应列匹配。

  • 这太神奇了,使用包装器可以完全分离计算列。在我的情况下,我需要它们来进行全文搜索的 matchinfo,但不想回到使用 db 游标,谢谢! (2认同)

Aka*_*ash 5

创建任务的子类假设

public class TaskDisplayModel extends Task{

@Ignore
private transient int noOfSubTask;

}
Run Code Online (Sandbox Code Playgroud)

那么你的查询将是

@Query("SELECT *,(SELECT count(*) FROM Task b  WHERE a._id = b.ParentId ) AS noOfSubTask FROM Task a ")
LiveData<List<TaskDisplayModel >> getTaskList();
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,只有当我去掉“@Ignore”注释时,这才有效。我认为只要没有将“TaskDisplayModel”作为要序列化的实体之一提供给数据库类,“noOfSubTask”字段就不会添加到任何数据库表中。关闭“@Ignore”还可以让它从查询结果中反序列化,查询结果可以直接来自字段,也可以通过计算得到。我还发现“transient”关键字是不必要的,但也许它提供了一些我不知道的好处。 (2认同)