Как заполнить поле столбца объекта в библиотеке комнат
У меня есть объект класса, как показано ниже
@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) частью запроса, но проблема в том, что это не столбец, поэтому библиотека комнаты не отображает его метод getTaskList в dao (автоматически сгенерированный) класс.
Есть ли способ заполнить поле без столбца объекта (например, noOfSubTask в моем случае) с помощью любого метода класса dao библиотеки комнат?
Ответы
Ответ 1
Я столкнулся с той же проблемой несколько дней назад и посмотрел на эту тему. Я использую классы data
Kotlin для создания объектов базы данных. Учитывая, что классы данных Kotlin не хорошо работают с наследованием, наследование не было жизнеспособным вариантом. Мое решение состояло в том, чтобы использовать ключевое слово @Embedded
в классе упаковки следующим образом:
data class TaskToDisplay(@Embedded
var task: Task,
var noOfSubTask: Int = 0)
Это решение не создает дополнительный столбец в базе данных и, самое главное, соответствует всем полям "Задачи" с столбцами "Ответ на вопрос".
Ответ 2
Создайте подкласс класса Задача
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();
Ответ 3
Я использую Kotlin, и у меня была аналогичная проблема, и ниже, как я ее решил.
-
Добавить дополнительное поле с? ( Вопросительный знак) для nullable, без аннотации @Ignore
@Entity(tableName = "task")
data class Task (
val name: String,
val parentId: Integer,
val userId: Integer,
val noOfSubTask: Integer?
)
-
Добавьте дополнительное поле (noOfSubTask в этом случае) в каждый запрос, который выбирает задачу в DAO.
@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>
...
}
Если это не сработает, вы можете попробовать RawQuery, который был недавно введен в Google I/O 2018.
Ответ 4
Вы должны переместить поле @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 для более подробной информации.