【问题标题】:Error in Room Query to Return Subset of Columns房间查询返回列子集时出错
【发布时间】:2018-11-22 19:37:11
【问题描述】:

我在玩 Room,但我无法找到解决问题的方法。

以下是数据。

表格

CREATE TABLE `Employee` (
    `id` INTEGER NOT NULL,
    `first_name` TEXT,
    `last_name` TEXT,
    PRIMARY KEY(`id`)
);

表格数据

实体

@Entity(tableName = "Employee")
public class Employee {

    @PrimaryKey
    private int id;

    @ColumnInfo(name = "first_name")
    private String firstName;

    @ColumnInfo(name = "last_name")
    private String lastName;

    ..Getters & Setters..
}

查询 1

@Query("Select * from Employee")
List<Employee> getEmployees();

结果 成功了

查询 2

@Query("Select first_name, last_name from Employee")
List<Employee> getEmployees();

结果

错误:查询返回的列在 ***.Employee 中没有字段 [id],即使它们被注释为非空或原始。查询返回的列:[first_name, last_name]

如果我将id 添加到Query 2 之上,它会起作用。

同样,如果我们在表中有一个Foreign Key 并且我们尝试查询列的子集,它会抛出错误。当我们在查询中同时添加 Primary KeyForeign Key 列时,就会出现错误。

问题 1 这是否意味着我们必须始终包含 Primary KeyForeign Key (如果存在)在查询中?

问题 2 它引发此类错误的幕后实际发生了什么?还是我做错了什么?

房间版 1.1.1

另外,提到了这个link,但它并没有解决我的主键问题。

【问题讨论】:

  • 只是猜测:“SELECT first_name FROM EMPLOYEE”只能产生一个 List。如果您坚持返回 List,则运行时必须填写一些默认值。但一方面主键列不能填充null,另一方面查询结果没有特定first_name值的正确id
  • @HimanshuAhuja:我在发布我的问题之前已经提到的链接。该链接讲述了其他字段的值,但我的与主键有关。
  • @0X0nosugar:谢谢,我知道了。 :) 我已经编辑了我的帖子。因为,我需要没有 ID 的 first_name 和 last_name 的员工列表。我现在能想到的唯一方法是,首先我必须使用 ID 进行查询,然后创建一个包装器以在没有 ID 的情况下发送。
  • @akashPatra 对于第二个查询,我也遇到了同样的错误。一旦我添加了 id 字段,它就可以正常工作,但我的要求是只得到两列。你找到解决办法了吗?

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


【解决方案1】:

要从多个字段中选择数据,请考虑以下示例。

来自文档

Room 允许您从查询中返回任何基于 Java 的对象 只要结果列的集合可以映射到返回的 目的。例如,您可以创建以下普通的基于 Java 的 对象 (POJO) 来获取用户的名字和姓氏:

public class NameTuple {
    @ColumnInfo(name = "first_name")
    public String firstName;

    @ColumnInfo(name = "last_name")
    public String lastName;
}

现在,您可以在查询方法中使用此 POJO:

@Dao
public interface MyDao {
    @Query("SELECT first_name, last_name FROM user")
    public List<NameTuple> loadFullName();
}

【讨论】:

  • 谢谢,这看起来不错。但是,如果我的查询是这样的“从员工中选择名字,姓氏”。我已经在帖子中更新了,因为我需要员工名单。
  • 但是这样我的查询 1 将失败。我必须使用相同的员工类同时运行查询 1 和查询 2。
  • 为什么会失败?您将保持您的员工类别不变。
【解决方案2】:

我认为你应该加入
@ColumnInfo(name = "id") @PrimaryKey private int id;

因为根据上面的查询抛出的错误,在您的实体中不存在这样的列作为 id,首先列 id 被称为表列 id 的匹配,然后通过注释设置主键

【讨论】:

  • @ColumnInfo(name = "id") 不会为代码增加价值。因为我的变量名与列名相同。
【解决方案3】:

除了@karan 的回答,pojo 还可用于使用 as 子句返回命名列

例如。

select sum(score) as total_score, sum(avg) as avg_score from mytable

其中 pojo 类的列名将分别是 total_score 和 avg_score ..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 2020-02-12
    • 2023-01-21
    • 1970-01-01
    相关资源
    最近更新 更多