房间插入“一对多”关系

时间:2018-11-14 13:23:45

标签: android one-to-many android-room

我想使用Android Room处理“一对多”关系。我可以轻松地使用@Relation [1]获取相关实体。根据[2] [3],Room中不存在对@Relation插入的本机支持。在[3] [4]中,关系是手动创建的(为“一个”对象和相关的“许多”对象手动设置了ID)。但是,我更喜欢将Autoincrement PK用作id(我通过其名称(字符串)访问“一个”对象)。

是否有“优雅的方式”使用自动增量PK插入相关实体(“一对多”)?

链接

  1. https://developer.android.com/reference/android/arch/persistence/room/Relation
  2. Android Room: Insert relation entities using Room
  3. https://issuetracker.google.com/issues/62848977
  4. https://android.jlelse.eu/android-architecture-components-room-relationships-bf473510c14a

1 个答案:

答案 0 :(得分:-1)

我发现 @Insert方法可以返回 long ,它是插入项的新rowId [1]。

  

如果@Insert方法仅接收1个参数,则它可以返回long,这是插入项的新rowId。如果参数是数组或集合,则应返回long []或List。

SQLite文档[2]说:

  

如果表包含INTEGER PRIMARY KEY类型的列,则该列将成为ROWID的别名。然后,您可以使用以下四个不同的名称中的任何一个来访问ROWID,即上述的三个原始名称,或者为INTEGER PRIMARY KEY列指定的名称。所有这些名称都是彼此的别名,并且在任何情况下都可以很好地工作。

所以我们可以做:

1)CompanyEntity.java

@Entity(tableName = "companies", indices = @Index(value = "name", unique = true)) public class CompanyEntity {
    @PrimaryKey (autoGenerate = true)
    public int id;
    @NonNull
    @ColumnInfo(name = "name")
    private final String mCompanyName;

    public CompanyEntity(@NonNull String companyName) {
        mCompanyName = companyName;
    }

    @NonNull
    public String getCompanyName() {
        return mCompanyName;
    }
}

2)EmployeeEntity.java

@Entity(tableName = "employee_list",
        foreignKeys = @ForeignKey(
                entity = CompanyEntity.class,
                parentColumns = "id",
                childColumns = "company_id",
                onDelete = CASCADE),
        indices = @Index("company_id"))
public class EmployeeEntity {
    @PrimaryKey(autoGenerate = true)
    public int id;
    @ColumnInfo(name = "company_id")
    private long mCompanyId;
    @NonNull
    @ColumnInfo(name = "name")
    private final String mName;

    public EmployeeEntity(@NonNull String name) {
        mName = name;
    }

    @NonNull
    public String getName() {
        return mName;
    }

    public long getCompanyId() {
        return mCompanyId;
    }

    public void setCompanyId(long companyId) {
        mCompanyId = companyId;
    }
}

3)EmployeeDao.java

@Dao
public abstract class EmployeeDao {

    @Query("SELECT * FROM companies")
    public abstract List<CompanyEntity> selectAllCompanies();

    @Transaction
    @Query("SELECT * FROM companies WHERE name LIKE :companyName")
    public abstract List<CompanyEmployees> getEmployeesByCompanyName(String companyName);

    @Transaction
    public void insert(CompanyEntity companyEntity, List<EmployeeEntity> employeeEntities) {

        // Save rowId of inserted CompanyEntity as companyId
        final long companyId = insert(companyEntity);

        // Set companyId for all related employeeEntities
        for (EmployeeEntity employeeEntity : employeeEntities) {
            employeeEntity.setCompanyId(companyId);
            insert(employeeEntity);
        }

    }

    // If the @Insert method receives only 1 parameter, it can return a long,
    // which is the new rowId for the inserted item.
    // https://developer.android.com/training/data-storage/room/accessing-data
    @Insert(onConflict = REPLACE)
    public abstract long insert(CompanyEntity company);

    @Insert
    public abstract void insert(EmployeeEntity employee);

}

似乎工作正常。

完整的源代码和示例项目: https://github.com/relativizt/android-room-one-to-many-auto-pk

链接

  1. https://developer.android.com/training/data-storage/room/accessing-data
  2. https://www.sqlite.org/autoinc.html