【问题标题】:How to do relation with array in one table but not in other?如何与一张表中的数组而不是另一张表中的数组建立关系?
【发布时间】:2021-02-05 20:23:19
【问题描述】:

(已更新) 我有这样的表格:

@Entity(tableName = "author_table")
public class Author {

  @PrimaryKey(autoGenerate = true)
  @ColumnInfo(name = "authorId")
  private int mAuthorId;
    
  @ColumnInfo(name = "authorName")
  private String mAuthorName;

  @ColumnInfo(name = "authorPublisherName")
  private String mAuthorPublisherName;

@Entity(tableName = "book_table")
public class Book{

  @PrimaryKey(autoGenerate = true)
  @ColumnInfo(name = "bookId")
  private int mBookId;

  @ColumnInfo(name = "bookName")
  private String mBookName;

  @ColumnInfo(name = "bookAuthors")
  private String[] bookAuthors;

我已经尝试并重试了好几个星期,但我无法得到任何工作。我已经尝试了解决方法来做到这一点,没有任何关系,没有运气。我已经尝试过各种方式的关系(外键、关系、连接等)。 “了解”数据库理论很奇怪,并且已经上过这方面的 uni 课程,但我无法让它与 Android Room 一起使用。 如何从一本书中获取或查询作者或作者出版商? (如果我问得正确的话......)

我想要这本书中所有作者的出版商。

另外,嵌入如何影响存储?如果我在每本书中“嵌入”一个作者(在 Android 应用中,有数千个作者和数千本书),那基本上会在每个 Book 实体中创建每个作者的副本吗?

我试过了:

  @Query("select authorPublisherNamefrom author_table where authorName IN (:names)")
  LiveData<List<String>> getAllThePublishers(List<String> names);

这给了我一个 1 的列表大小。我假设它只是 ping 查询列表中得分为 true 的名字。

然后我尝试创建另一个类,例如 @sergiy tikhonov 的评论方式和来自 How can I represent a many to many relation with Android Room? 的方式:

@Entity(primaryKeys = {"authName", "bookAuth"})
public class BookAndAuthors{

  private int authName, bookAuth;
}

public class BooksWithAuthors{

  @Embedded
  public Book book;
  @Relation(
      parentColumn = "authorName",
      entityColumn = "bookAuthors",
      associateBy = @Junction(
          value = BookAndAuthors.class,
          parentColumn = "authName",
          entityColumn = "bookAuth")
  )
  public List<FastMoveEntity> fastMoveList;
}

但现在我不知道如何查询以获取 Publishers (authorPublisherName)。

旁注:sergiy 的回答是在课堂上绑定钥匙,我不知道该怎么做或让它发挥作用。是否必须以某种方式插入该关系?

【问题讨论】:

    标签: android sqlite android-room


    【解决方案1】:

    如果子表使用字符串数组而父表具有字符串值,我如何/可以引用或使用外键?

    我建议不要搜索此问题的答案,而只是更改表的结构。对于所有关系数据库(以及其中的 Sqlite)来说,好的(并且经过时间证明)方法是实现表的 normalization

    因此,不要使用两个表,而是使用三个表。第三个是BookAuthors。同样常见的方法是为您的表使用整数主键。

    @Entity(tableName = "author_table")
    public class Author {
    
      @PrimaryKey
      @ColumnInfo(name = "id")
      public int id;
    
      @ColumnInfo(name = "authorName")
      private String authorName;
      ........
    
    @Entity(tableName = "book_table")
    public class Book {
    
      @PrimaryKey
      @ColumnInfo(name = "id")
      public int id;
    
      @ColumnInfo(name = "bookName")
      private String bookName;
      ........
    
    @Entity(tableName = "book_authors_table", primaryKeys = {"bookId", "authorId"}) // you could set there foreign keys for both fields if you want
    public class BookAuthors {
     
      @ColumnInfo(name = "bookId")
      public int bookId;
    
      @ColumnInfo(name = "authorId")
      public int authorId;
    }
    
    

    通过这种结构,您可以轻松获得所需的任何数据连接(所有作者的书籍和所有书面书籍的作者)。如何实现 - 看看in documentation for many-to-many relations

    【讨论】:

    • 我的 id 是自动生成的,与其他实体没有任何共同之处。我无法理解如何在您的解决方案中工作。仅当实体以某种方式插入到带有第三类的表中时,它才有效吗?另外,您的答案不包括查询包含一个表而不是另一个表中的数组或列表的列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多