【问题标题】:Room Android, select on two tablesRoom Android,在两张桌子上选择
【发布时间】:2021-10-20 10:29:08
【问题描述】:

我是 Room 的新手,我正在为此苦苦挣扎。 我想对名为 Project 和 Tasks 的两个表进行简单的选择。这是两个类和第三个类来链接它们:


    @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
    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();
                                        ^

我不知道我做错了什么。所以非常感谢你能给我的任何帮助

【问题讨论】:

    标签: java select embedded android-room


    【解决方案1】:

    由于您的 TaskWithProject 类嵌入了项目,因此它期望获取项目的列,然后从中构建任务,因此当您使用 SELECT * FROM Task 时,它没有相关的列 (加入它但可能无法按预期工作)。

    • TaskWithProject 真的是 ProjectWithTask。

    因此,要么使用SELECT * FROM project,要么使用嵌入了任务并将项目作为@Relation 的POJO(使用SELECT * FROM task)。

    【讨论】:

    • 使用第一个解决方案和这样的课程TaskWithProject { @Embedded public Project project; @Relation(parentColumn = "id", entityColumn = "projectId") public List&lt;Task&gt; tasks; } 我有这个错误Compilation of classes com.cleanup.todoc.database.Dao.TaskDao_Impl$3 requires its nest mates com.cleanup.todoc.database.Dao.TaskDao_Impl$5 (unavailable) to be on program or class path.(Classes com.cleanup.todoc.database.Dao.TaskDao_Impl, (...) from the same nest are on class path). 你知道为什么吗?
    • @Emmcy 否但我怀疑您可能需要进行清理或重建,_Impl 类是由房间生成的。说不需要/使用连接,因为 Room 通过单独的查询获取 @Relation,它所需要(和使用)的只是构建嵌入式实际连接的数据,如果任何列名相同,可能会导致意外结果(我相信它可能会得到任何同名的最后一列的值)。很高兴看到您有 List&lt;Task&gt; tasks; 会说您可能想要这样,以便您完成项目的所有任务。
    • 我已将类名从 TaskWithProject 更改为 ProjectWithTasks 并且错误消失了(也许它已经强制某种重建)。非常感谢您非常清楚的解释。
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多