我有一个PostDAO,看起来像这样。

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

和Post 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
    }
}

如您所见,用户对象是 @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 Object上的Embedded user字段的hasNewMusic字段填充有subQuery。

尝试了上面的方法,无法正常工作,不确定是否可以执行此操作。

最佳答案

首先,在SQLite和Room中没有 boolean 值(如我所读),将1和0 INTEGER值映射到 boolean 值的true和false(请参阅Hardcode Boolean Query In Room Database)。顾名思义,sound_time不受1和0值的限制。因此,尝试将sound_time转换为它。

另外,我认为您滥用了@Embedded批注。它用于将一个表的列放入可以出于某种原因进行分组的类。例如,此处(@Embedded)编写为:



因此,您应该通过PostDAO::getPosts()加上您的巨人选择来修改INNER JOIN方法以返回用户的列。而且我不保证这会成功,因为我还没有这样做。同样由于某些原因,这很糟糕。

或者,您可以保留“不带用户发布”字段,并创建一个名为PostWithUser的实体,并使用@Relation批注。 Wich更好,建议在文档中使用。

UPD:

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

  • 从帖子中删除用户字段。
  • 将ForeignKey添加到Post。我将使用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
    }
    
  • 将PostWithUserDao设为:
    class PostWithUserDao {
        @Query("select * from post, user where post.userId = user.user_id")
        fun getPostsWithUsers(): List<PostWithUser>
    }
    

  • 而且由于我在这里无法适应sound_time子查询,因此我将在第二个查询中执行此操作,但是如果您知道如何执行此操作,我认为它可以工作。

    另请参见:Room database with one-to-one relation

    10-08 17:58