房间 Android、select 两张桌子
Room Android, select on two tables
我是 Room 的新手,我正在努力使用它。
我想对名为 Project 和 Tasks 的两个表做一个简单的 select。这是两个 classes 和第三个到 link 他们:
@Entity
public class Project {
@PrimaryKey(autoGenerate = true)
private final long id;
@NonNull
private final String name;
@ColorInt
private final Integer color;
}
@Entity(foreignKeys = @ForeignKey(entity = Project.class, parentColumns = "id", childColumns = "projectId"))
public class Task {
@PrimaryKey(autoGenerate = true)
private long idTask;
// clé commune
private long projectId;
@NonNull
private String nameTask;
public long creationTimestamp;
// constructor, getters, setters
}
public class TaskWithProject {
@Embedded public Project project;
@Relation(parentColumn = "id", entityColumn = "projectId")
public Task task;
}
我在 Dao 中尝试了很多东西 class。这是其中两个:
@Dao
public interface TaskDao {
(...)
// Solution 1
@Query("SELECT * FROM Task t JOIN Project p ON t.projectId = p.id")
LiveData<List<TaskWithProject>> getTaskWithProject();
// Solution 2 from https://developer.android.com/training/data-storage/room/relationships
@Transaction
@Query("SELECT * FROM Task")
LiveData<List<TaskWithProject>> getTaskWithProject();
我的数据库中填充了这些数据(在数据库检查器中没有问题):
projectDao.insertProject(new Project(0, "Projet Tartampion", 0xFFEADAD1));
projectDao.insertProject(new Project(0, "Projet Lucidia", 0xFFB4CDBA));
projectDao.insertProject(new Project(0, "Projet " + "Circus", 0xFFA3CED2));
taskDao.insertTask(new Task(0, 1, "Task 1 - Tartampion"));
taskDao.insertTask(new Task(0, 1, "Task 2 - Tartampion"));
taskDao.insertTask(new Task(0, 2, "Task 1 - Lucidia"));
我用这个函数获取数据:
public LiveData<List<TaskViewStateItem>> getAllTasks() {
return Transformations.map(repository.getTaskWithProject(), tasks -> {
List<TaskViewStateItem> liststateitems = new ArrayList<>();
for (TaskWithProject t : tasks) {
Log.i(TAG, "getAllTasks: "+ t.toString());
liststateitems.add(new TaskViewStateItem(t.task.getIdTask(), t.task.getNameTask(), t.project.getName(), t.project.getColor(), t.task.getCreationTimestamp()));
}
}
return liststateitems;
});
}
使用上面的解决方案 1,我有 3 个条目,但有一个重复条目。
I/Log ViewModel: getAllTasks: TaskWithProject{project=Project{id=1, name='Projet Tartampion', color=-1385775}, task=Task{idTask=2, projectId=1, nameTask='Task 2 - Tartampion', creationTimestamp=1634723235}}
I/Log ViewModel: getAllTasks: TaskWithProject{project=Project{id=1, name='Projet Tartampion', color=-1385775}, task=Task{idTask=2, projectId=1, nameTask='Task 2 - Tartampion', creationTimestamp=1634723235}}
getAllTasks: TaskWithProject{project=Project{id=2, name='Projet Lucidia', color=-4928070}, task=Task{idTask=3, projectId=2, nameTask='Task 1 - Lucidia', creationTimestamp=1634723235}}
方案2编译不通过
error: Not sure how to convert a Cursor to this method's return type (com.cleanup.todoc.model.TaskWithProject).
LiveData<List<TaskWithProject>> getTaskWithProject();
^
我不知道我做错了什么。所以非常感谢你能给我的任何帮助
由于您的 TaskWithProject class 嵌入了项目,因此它期望获取项目的列,然后从中构建任务,因此当您使用 SELECT * FROM Task
它时没有相关的列(它有连接但可能无法按预期工作)。
- 真的 TaskWithProject 是 ProjectWithTask。
因此,要么使用 SELECT * FROM project
,要么使用 POJO 嵌入任务和项目作为 @Relation(使用 SELECT * FROM task
)。
我是 Room 的新手,我正在努力使用它。 我想对名为 Project 和 Tasks 的两个表做一个简单的 select。这是两个 classes 和第三个到 link 他们:
@Entity
public class Project {
@PrimaryKey(autoGenerate = true)
private final long id;
@NonNull
private final String name;
@ColorInt
private final Integer color;
}
@Entity(foreignKeys = @ForeignKey(entity = Project.class, parentColumns = "id", childColumns = "projectId"))
public class Task {
@PrimaryKey(autoGenerate = true)
private long idTask;
// clé commune
private long projectId;
@NonNull
private String nameTask;
public long creationTimestamp;
// constructor, getters, setters
}
public class TaskWithProject {
@Embedded public Project project;
@Relation(parentColumn = "id", entityColumn = "projectId")
public Task task;
}
我在 Dao 中尝试了很多东西 class。这是其中两个:
@Dao
public interface TaskDao {
(...)
// Solution 1
@Query("SELECT * FROM Task t JOIN Project p ON t.projectId = p.id")
LiveData<List<TaskWithProject>> getTaskWithProject();
// Solution 2 from https://developer.android.com/training/data-storage/room/relationships
@Transaction
@Query("SELECT * FROM Task")
LiveData<List<TaskWithProject>> getTaskWithProject();
我的数据库中填充了这些数据(在数据库检查器中没有问题):
projectDao.insertProject(new Project(0, "Projet Tartampion", 0xFFEADAD1));
projectDao.insertProject(new Project(0, "Projet Lucidia", 0xFFB4CDBA));
projectDao.insertProject(new Project(0, "Projet " + "Circus", 0xFFA3CED2));
taskDao.insertTask(new Task(0, 1, "Task 1 - Tartampion"));
taskDao.insertTask(new Task(0, 1, "Task 2 - Tartampion"));
taskDao.insertTask(new Task(0, 2, "Task 1 - Lucidia"));
我用这个函数获取数据:
public LiveData<List<TaskViewStateItem>> getAllTasks() {
return Transformations.map(repository.getTaskWithProject(), tasks -> {
List<TaskViewStateItem> liststateitems = new ArrayList<>();
for (TaskWithProject t : tasks) {
Log.i(TAG, "getAllTasks: "+ t.toString());
liststateitems.add(new TaskViewStateItem(t.task.getIdTask(), t.task.getNameTask(), t.project.getName(), t.project.getColor(), t.task.getCreationTimestamp()));
}
}
return liststateitems;
});
}
使用上面的解决方案 1,我有 3 个条目,但有一个重复条目。
I/Log ViewModel: getAllTasks: TaskWithProject{project=Project{id=1, name='Projet Tartampion', color=-1385775}, task=Task{idTask=2, projectId=1, nameTask='Task 2 - Tartampion', creationTimestamp=1634723235}}
I/Log ViewModel: getAllTasks: TaskWithProject{project=Project{id=1, name='Projet Tartampion', color=-1385775}, task=Task{idTask=2, projectId=1, nameTask='Task 2 - Tartampion', creationTimestamp=1634723235}}
getAllTasks: TaskWithProject{project=Project{id=2, name='Projet Lucidia', color=-4928070}, task=Task{idTask=3, projectId=2, nameTask='Task 1 - Lucidia', creationTimestamp=1634723235}}
方案2编译不通过
error: Not sure how to convert a Cursor to this method's return type (com.cleanup.todoc.model.TaskWithProject).
LiveData<List<TaskWithProject>> getTaskWithProject();
^
我不知道我做错了什么。所以非常感谢你能给我的任何帮助
由于您的 TaskWithProject class 嵌入了项目,因此它期望获取项目的列,然后从中构建任务,因此当您使用 SELECT * FROM Task
它时没有相关的列(它有连接但可能无法按预期工作)。
- 真的 TaskWithProject 是 ProjectWithTask。
因此,要么使用 SELECT * FROM project
,要么使用 POJO 嵌入任务和项目作为 @Relation(使用 SELECT * FROM task
)。