当前位置: 首页 > 知识库问答 >
问题:

Android Room:如何在自定义查询中使用嵌入式

欧阳高昂
2023-03-14

我有一把后刀,看起来像这样。

@Dao
public interface PostDAO extends DAOTemplate<Post> {
    @Query("SELECT * FROM posts order by time DESC")
    LiveData<List<Post>> getPosts();
}

和邮政Pojo是。

@Keep
@Entity(tableName = "posts")
open class Post : Serializable, Cloneable {
    @NonNull
    @PrimaryKey
    var id: String? = null

    var text: String? = null

    var time: Long = 0
    var uid: String? = null
    @Embedded
    var user: User? = null

    public override fun clone(): Post {
        return super.clone() as Post
    }
}

如您所见,User对象是@Embedded

和用户的DAO

@Dao
public interface UserDAO extends DAOTemplate<User> {
@Query("SELECT *,(SELECT sound_time FROM sounds WHERE sound_uid =:id AND " +
                "(sound_time < strftime('%s', 'now'))) AS hasNewMusic    " +
                "FROM users WHERE user_uid = :id")
        LiveData<User> getUser(String id);
}

和用户Pojo

@Keep
@IgnoreExtraProperties
@Entity(tableName = "users")
class User : ModelTemplate() {
    @NonNull
    @PrimaryKey
    @ColumnInfo(name = "user_uid")
    override var id: String? = null;

    var name: String? = null
    var icon: String? = null

    var hasNewMusic: Boolean = false
}

现在,我想让Post对象上的嵌入式用户字段,hasNewMusic,填充一个子查询。

尝试了上述方法,但没有奏效,也不确定这是否是解决问题的方法。

共有1个答案

隗俊誉
2023-03-14

首先,SQLite中没有布尔值,Room(如我所读)将1和0整数值映射为布尔值的true和false(请参阅Room数据库中的硬编码布尔查询)。根据名称,我可以猜测声音时间不受1和0值的限制。所以,试着把声音转换成时间。

另外,我认为你误用了@嵌入式注释。它用于将一个表中的列放入可以按某种原因分组的类中。例如这里(@Embedded)是这样写的:

因此,如果您有一个返回street、latitude、longitude的查询,Room将正确地构造一个Address类。

因此,您应该修改PostDAO::getPosts()方法,通过internal JOIN加上巨大的选择来返回用户的列。我不能保证这会起作用,因为我还没有这么做。此外,出于某些原因,这是不好的。

或者,您可以将Post保留为没有用户字段,并创建一个名为PostBackUser的实体,并使用@Relation注释。Wich更好,建议留档。

UPD:

要获取两个实体,请尝试以下操作:

>

  • 从文章中删除用户字段。
  • 将ForeignKey添加到发布。我将使用userId,如果uid已经是这样使用它:

    @Entity(tableName = "posts",
            foreignKeys = [ForeignKey(
                    entity = Post::class,
                    parentColumns = ["user_id"], //from ColumnInfo of User class
                    childColumns = ["userId"],
                    onDelete = CASCADE)],
            indices = [Index(value = ["userId"]]))
    class Post {
    
        @PrimaryKey
        var id: String? = null
    
        var userId: String? = null
    
        //...else code....
    
    }
    

    使用用户类制作PostWithUser:

    class PostWithUser {
        @Embedded lateinit var post: Post
        @Embedded lateinit var user: User 
    }
    

    制作PostRetUser道:

    class PostWithUserDao {
        @Query("select * from post, user where post.userId = user.user_id")
        fun getPostsWithUsers(): List<PostWithUser>
    }
    

    由于我没有设法适应这里sound_time子查询,我将在第二个查询中执行它,但是如果你想出如何执行它,我认为它可以工作。

    还可以看到:一对一关系的房间数据库

  •  类似资料:
    • 我是Spring Jpa和Hibernate的新手。我试图使用一个定制函数从Oracle数据库中获取数据。我可以定义一个实体及其相关的服务、实现和存储库。此外,我通过使用< code>registerFunction创建了一个新的定制Oracle方言,如下所示。 所以我有两个问题: 1)在我的Oracle数据库中,函数位于不同的模式下。我需要指定它的模式吗?如果是的话怎么做?还是hibernate

    • 我在这里创建了一个类似于教程的Web应用程序:https://spring.io/guides/tutorials/react-and-spring-data-rest/ . 我已经添加了后gresql数据库,一切正常。我有一个基本查询查找我的存储库中的By用户名(字符串名称),工作正常。我的问题是,由于某种原因我无法创建自定义查询,例如 . 假设我做了一个测试,我只想得到这个语句的值。我说的不能

    • 我想使用@Query批注从具有@OneTo许多关系的实体创建左连接查询。 母公司是: 孩子: 对于DAO,我确实喜欢以下内容: 显然,它是错误的,因为生成的查询是: 选择payment1。uuid为uuid1_9_,付款1_。注册时内部加入付款1的注册金额。uuid=payment1_uid。uuid在哪里注册。效果=? 在生成关系表时: 对我来说,正确的查询应该是这样的: 选择p.*从注册r加入

    • 我是Spring Data投影的新手,我正在尝试在一个新项目中使用此功能。 特别是,我想在与复杂查询关联的回购方法上使用投影。 我用注释注释了我的方法,并声明了一个JPA查询,其中包含几个连接的表/实体和一个复杂的where条件。 在本文中,我了解到可以使用基于接口的投影和基于类的投影,但只有第一个支持嵌套投影。 我需要嵌套投影,但似乎只有使用基于接口的投影才支持此功能,并且这种方法仅适用于自动生

    • 我有一个整数参数。我需要编写一个定制的Spring JPA查询,其中等效的SQL是<(1,2)中的code>和x.propertyStatuid。 我在SpringDataJPA文档中看到关键字是“in”,如

    • 问题内容: 我正在尝试在Formik中使用DatePicker。但是,当我单击DatePicker的日期时,其表单值不会更改。相反,我得到了这个错误: 未捕获到的TypeError:e.persist不是Formik._this.handleChange上的函数(formik.es6.js:5960) 我简化代码,下面的代码 我用谷歌搜索了一些文档,https://github.com/jared