Room - 如何从 DAO 查询中获取 COUNT 值?

Posted

技术标签:

【中文标题】Room - 如何从 DAO 查询中获取 COUNT 值?【英文标题】:Room - How to get COUNT value from DAO query? 【发布时间】:2019-11-12 17:09:03 【问题描述】:

我的 Room DAO 中有一个查询(对于提供的 countryId)查询我的 share_groups 表并返回包含 num_twitter_users 数字的行(通过计算相关的填充行数来计算) share_group_individuals 表)。

这是查询代码:

@Query("SELECT `share_groups`.`_id`, `share_group_name`, `share_group_description`, `share_group_instructions`, `share_group_order`, `share_group_is_visible`, `share_groups`.`last_modified`" +

    // `num_twitter_users` will contain the number of share_group_individuals within this share_group that have a Twitter username.
    ", COUNT(DISTINCT(CASE WHEN (`share_group_individuals`.`share_group_individual_twitter` IS NOT NULL AND `share_group_individuals`.`share_group_individual_twitter` != '') THEN `share_group_individuals`.`_id` ELSE NULL END)) AS `num_twitter_users`" +

    " FROM `share_groups`" +

    // Join with `share_group_individuals` - on countryId
    " LEFT JOIN `share_group_individuals` ON (`share_group_individuals`.`share_group_id` = `share_groups`.`_id`" +
    " AND `share_group_individuals`.`share_group_individual_country_id` = :countryId)" +

    // Search on countryId
    " WHERE `share_group_individuals`.`share_group_individual_country_id` = :countryId" +

    " GROUP BY `share_groups`.`share_group_name`, `share_group_individuals`.`share_group_id`" +

    // Only return share_groups that contain at least 1 share_group_individual with a Twitter account
    " HAVING `num_twitter_users` > 0" +

    " ORDER BY `share_group_order` ASC")
LiveData<List<ShareGroup>> getAllShareGroups(long countryId);

但是,我无法从返回的 LivaData&lt;List&lt;ShareGroup&gt;&gt; 访问 num_twitter_users 值。

我想知道解决方案的一部分是否可能是创建一个ShareGroupWithData POJO(因此从我的查询中返回一个LivaData&lt;List&lt;ShareGroupWithData&gt;&gt;)但是,如果这是正确的方法,我将如何填充numTwitterUsers ShareGroupWithData 类中的变量?

我在网上或official documentation 中找不到任何关于此的信息,因此非常感谢您指出正确的方向和/或一些示例代码。

为了完整起见,我的share_groups 表由该实体表示:

@Entity(tableName = "share_groups")
public class ShareGroup 

    @PrimaryKey
    @ColumnInfo(name = "_id")
    private long id;

    @NonNull
    @ColumnInfo(name = "share_group_name")
    private String shareGroupName;

    @ColumnInfo(name = "share_group_description")
    private String shareGroupDescription;

    @ColumnInfo(name = "share_group_instructions")
    private String shareGroupInstructions;

    @ColumnInfo(name = "share_group_order", defaultValue = "10")
    private int shareGroupOrder;

    @ColumnInfo(name = "share_group_is_visible", defaultValue = "1")
    private boolean shareGroupIsVisible;

    @ColumnInfo(name = "last_modified")
    private long lastModified;

...

而我的share_groups_individual 表就是由这个实体表示的:

@Entity(tableName = "share_group_individuals",
        indices = @Index(name = "index_share_group_id", value = "share_group_id"),
        foreignKeys = @ForeignKey(entity = ShareGroup.class, parentColumns = "_id", childColumns = "share_group_id", onDelete = ForeignKey.CASCADE)
)
public class ShareGroupIndividual 

    @PrimaryKey
    @ColumnInfo(name = "_id")
    private long id;

    @ColumnInfo(name = "share_group_id")
    private long shareGroupId;

    @ColumnInfo(name = "share_group_individual_country_id", defaultValue = "-1")
    private long shareGroupIndividualCountryId;

    @ColumnInfo(name = "share_group_individual_name")
    private String shareGroupIndividualName;

    @ColumnInfo(name = "share_group_individual_twitter")
    private String shareGroupIndividualTwitter;

...

【问题讨论】:

如果您为查询结果创建一个单独的类,它可能会起作用。像这样的东西:data class ResultType( @Embedded val grup: ShareGroup, @Embedded val individual: ShareGroupIndividual, val num_twitter_users: Int ) @Daniil 感谢您的帮助,但我现在已经搞定了。 【参考方案1】:

最后,我通过创建这样的 POJO 解决了这个问题:

public class ShareGroupWithData 

    @Embedded
    public ShareGroup shareGroup;

    @ColumnInfo(name = "num_twitter_users", defaultValue = "0")
    public int numTwitterUsers;
...

我的 DAO 代码更改为:

LiveData&lt;List&lt;ShareGroupWithData&gt;&gt; getAllShareGroupsWithData(long countryId);

【讨论】:

以上是关于Room - 如何从 DAO 查询中获取 COUNT 值?的主要内容,如果未能解决你的问题,请参考以下文章

Room:如何检查行是不是存在

kotlin 升级到 1.6.0 后如何在 Room Dao 中使用挂起修饰符?

Android Room Dao:按 CASE 排序不起作用

如何在 Room @Query 中使用 ROW_NUMBER()?

Android 房间查询返回 null

Android Room - 使用自动生成获取新插入行的 id - MVVM 版本