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

时间:2017-11-14 09:33:40

标签: java android sqlite android-room android-architecture-components

我有一个类实体,如下所示

@Entity
public class Task {    
    private String name; 
    private Integer ParentId;
    private Integer userId;   
    @Ignore
    private int noOfSubTask;
}
在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();
}

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

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

4 个答案:

答案 0 :(得分:7)

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

data class TaskToDisplay(@Embedded
                         var task: Task,
                         var noOfSubTask: Int = 0)

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

答案 1 :(得分:2)

创建一个Task类的子类

public class TaskDisplayModel extends Task{

@Ignore
private transient int noOfSubTask;

}

然后您的查询将是

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

答案 2 :(得分:0)

我正在使用Kotlin,但遇到了类似的问题,下面是我的解决方法。

  1. 添加带有?(问号)的其他字段,可为空,不带@Ignore注释

    @Entity(tableName = "task")
    data class Task (
        val name: String,
        val parentId: Integer,
        val userId: Integer,
        val noOfSubTask: Integer?
    )
    
  2. 向在DAO中选择Task的每个查询添加附加字段(在这种情况下为noOfSubTask)。

    @Dao
    interface TaskDao {
        @Query("SELECT *,(SELECT count(*) FROM Task b  WHERE a._id = b.ParentId ) AS noOfSubTask FROM Task a ")
        fun getTaskList(): LiveData<List<Task>>
    
        @Query("SELECT *, NULL AS noOfSubTask FROM Task WHERE name = :name")
        fun getTask(name: String): LiveData<Task>
    
        ...
    }
    

如果这不起作用,您可以尝试最近在Google I / O 2018中引入的RawQuery

答案 3 :(得分:0)

您应将@Ignore字段移出构造函数,如下所示:

样本数据:

@Entity(primaryKeys = ["id"])
data class User(
    @SerializedName("id")
    val id: Int,

    @SerializedName("name")
    val name: String,

    @SerializedName("age")
    val age: Int
) {
   @Ignore
   val testme: String?
}

有关更多详细信息,请参见github discussion