具有相同名称的键的 Kotmin Room crossRef 实体
Kotmin Room crossRef Entity with keys having the same name
我正在创建一个 CRUD 工厂。基本上,我所有的实体都将从以 id
作为主键的 BaseEntity 继承
我试图了解如何为 M2M 关系创建交叉引用 table。
这是一个没有继承的简化示例。 ArticlesEntity
有很多 MagasinsEntity
和 MagasinsEntity
很多 ArticlesEntity
。实体 ArticlesMagasinsCrossRef
是结点
但是 ArticlesEntity 和 MagasinsEntity 都有 id
作为主键。
@Entity(
tableName = "articles"
)
data class ArticlesEntity(
@PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
val title: String,
)
@Entity(tableName = "magasins")
data class MagasinsEntity(
@PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
val nomMagasin: String
)
@Entity(
tableName = "articles_magasins"
)
data class ArticlesMagasinsCrossRefEntity(
val id: UUID, // how is it possible here to have the id of Articles ?
val id: UUID // how is it possible here to have the id of Magasins ?
)
编辑
我当然尝试更改列的名称:
data class ArticlesMagasinsCrossRefEntity(
val articleRd: UUID
val magasinId: UUID
)
但是关系数据构建失败class:例如
data class RelMagasinWithArticles(
@Embedded val magasin: MagasinsEntity,
@Relation(
parentColumn = "magasinId",
entityColumn = "id",
associateBy = Junction(ArticlesMagasinsCrossRefEntity::class)
)
val articles: List<ArticleEntity>
)
您需要使用 Junction 的 parentColumn 和 entityColumn 参数,例如
data class RelMagasinWithArticles(
@Embedded val magasin: MagasinsEntity,
@Relation(
parentColumn = "id", /* The column in the @Embedded table (articles) */
entityColumn = "id", /* The column in the Related table (magasins) */
associateBy = Junction(
ArticlesMagasinsCrossRefEntity::class,
parentColumn = "magasinId", /* The column in the junction table that maps to the @Embedded table */
entityColumn = "articleRd" /* The column in the junction table that maps to the @Relation Table */
)
)
val articles: List<ArticlesEntity>
)
备注
您还需要为 ArticlesMagasinsCrossRefEntity class 定义一个主键,例如:-
@Entity(
tableName = "articles_magasins",
/*<<<<< all Room table MUST have a primary key */
/* as primary key on a single column would be restrictive use a composite
primary key
*/
primaryKeys = ["articleRd","magasinId"]
)
data class ArticlesMagasinsCrossRefEntity(
/* Cannot have identical member names - i.e. only 1 could be id
val id: UUID, // how is it possible here to have the id of Articles ?
val id: UUID // how is it possible here to have the id of Magasins ?
*/
val articleRd: UUID,
/* Room will issue warning if the is no index on the 2nd column */
@ColumnInfo(index = true)
val magasinId: UUID
)
- 请注意,您可以使用@ColumnInfo 名称参数来指定列名称。
演示
所以使用你的代码,建议的代码覆盖你的代码,并使用以下@Dao 接口:-
@Dao
interface AllDao {
@Insert
fun insert(articlesEntity: ArticlesEntity)
@Insert
fun insert(magasinsEntity: MagasinsEntity)
@Insert
fun insert(articlesMagasinsCrossRefEntity: ArticlesMagasinsCrossRefEntity)
@Query("SELECT * FROM magasins")
@Transaction
fun getMWA(): List<RelMagasinWithArticles>
}
一个合适的@Database注解class和代码在activity:-
lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
val a1uuid = UUID.randomUUID()
val a2uuid = UUID.randomUUID()
val a3uuid = UUID.randomUUID()
dao.insert(ArticlesEntity(a1uuid, "Article1"))
dao.insert(ArticlesEntity(a2uuid,"Article2"))
dao.insert(ArticlesEntity(a3uuid,"Article3"))
val m1uuid = UUID.randomUUID()
val m2uuid = UUID.randomUUID()
val m3uuid = UUID.randomUUID()
dao.insert(MagasinsEntity(m1uuid,"Magasin1"))
dao.insert(MagasinsEntity(m2uuid,"Magasin2"))
dao.insert(MagasinsEntity(m3uuid,"Magasin3"))
dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m2uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m3uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a2uuid,m1uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m1uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m2uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m3uuid))
val sb = StringBuilder()
for(mwa in dao.getMWA()) {
sb.append("\nMagasin is ${mwa.magasin.nomMagasin}. ID is ${mwa.magasin.id} it has ${mwa.articles.size} articles. They are:-" )
for (article in mwa.articles) {
sb.append("\n\tArticle is ${article.title} ID is ${article.id}")
}
}
Log.d("DBINFO",sb.toString())
}
日志的输出是:-
D/DBINFO: Magasin is Magasin1. ID is 0f3384ee-6232-423e-b2f1-a12ebdac6487 it has 2 articles. They are:-
Article is Article2 ID is 2729d017-de05-41d2-8de3-8351dfca0a6b
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
Magasin is Magasin2. ID is ba649833-a8ce-4cf2-a1b8-bcab8f7a7d0a it has 2 articles. They are:-
Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
Magasin is Magasin3. ID is eed6f0a5-0825-4cda-9eb4-c4e973a49738 it has 2 articles. They are:-
Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
我正在创建一个 CRUD 工厂。基本上,我所有的实体都将从以 id
作为主键的 BaseEntity 继承
我试图了解如何为 M2M 关系创建交叉引用 table。
这是一个没有继承的简化示例。 ArticlesEntity
有很多 MagasinsEntity
和 MagasinsEntity
很多 ArticlesEntity
。实体 ArticlesMagasinsCrossRef
是结点
但是 ArticlesEntity 和 MagasinsEntity 都有 id
作为主键。
@Entity(
tableName = "articles"
)
data class ArticlesEntity(
@PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
val title: String,
)
@Entity(tableName = "magasins")
data class MagasinsEntity(
@PrimaryKey(autoGenerate = false) val id: UUID = UUID.randomUUID(),
val nomMagasin: String
)
@Entity(
tableName = "articles_magasins"
)
data class ArticlesMagasinsCrossRefEntity(
val id: UUID, // how is it possible here to have the id of Articles ?
val id: UUID // how is it possible here to have the id of Magasins ?
)
编辑 我当然尝试更改列的名称:
data class ArticlesMagasinsCrossRefEntity(
val articleRd: UUID
val magasinId: UUID
)
但是关系数据构建失败class:例如
data class RelMagasinWithArticles(
@Embedded val magasin: MagasinsEntity,
@Relation(
parentColumn = "magasinId",
entityColumn = "id",
associateBy = Junction(ArticlesMagasinsCrossRefEntity::class)
)
val articles: List<ArticleEntity>
)
您需要使用 Junction 的 parentColumn 和 entityColumn 参数,例如
data class RelMagasinWithArticles(
@Embedded val magasin: MagasinsEntity,
@Relation(
parentColumn = "id", /* The column in the @Embedded table (articles) */
entityColumn = "id", /* The column in the Related table (magasins) */
associateBy = Junction(
ArticlesMagasinsCrossRefEntity::class,
parentColumn = "magasinId", /* The column in the junction table that maps to the @Embedded table */
entityColumn = "articleRd" /* The column in the junction table that maps to the @Relation Table */
)
)
val articles: List<ArticlesEntity>
)
备注
您还需要为 ArticlesMagasinsCrossRefEntity class 定义一个主键,例如:-
@Entity(
tableName = "articles_magasins",
/*<<<<< all Room table MUST have a primary key */
/* as primary key on a single column would be restrictive use a composite
primary key
*/
primaryKeys = ["articleRd","magasinId"]
)
data class ArticlesMagasinsCrossRefEntity(
/* Cannot have identical member names - i.e. only 1 could be id
val id: UUID, // how is it possible here to have the id of Articles ?
val id: UUID // how is it possible here to have the id of Magasins ?
*/
val articleRd: UUID,
/* Room will issue warning if the is no index on the 2nd column */
@ColumnInfo(index = true)
val magasinId: UUID
)
- 请注意,您可以使用@ColumnInfo 名称参数来指定列名称。
演示
所以使用你的代码,建议的代码覆盖你的代码,并使用以下@Dao 接口:-
@Dao
interface AllDao {
@Insert
fun insert(articlesEntity: ArticlesEntity)
@Insert
fun insert(magasinsEntity: MagasinsEntity)
@Insert
fun insert(articlesMagasinsCrossRefEntity: ArticlesMagasinsCrossRefEntity)
@Query("SELECT * FROM magasins")
@Transaction
fun getMWA(): List<RelMagasinWithArticles>
}
一个合适的@Database注解class和代码在activity:-
lateinit var db: TheDatabase
lateinit var dao: AllDao
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
val a1uuid = UUID.randomUUID()
val a2uuid = UUID.randomUUID()
val a3uuid = UUID.randomUUID()
dao.insert(ArticlesEntity(a1uuid, "Article1"))
dao.insert(ArticlesEntity(a2uuid,"Article2"))
dao.insert(ArticlesEntity(a3uuid,"Article3"))
val m1uuid = UUID.randomUUID()
val m2uuid = UUID.randomUUID()
val m3uuid = UUID.randomUUID()
dao.insert(MagasinsEntity(m1uuid,"Magasin1"))
dao.insert(MagasinsEntity(m2uuid,"Magasin2"))
dao.insert(MagasinsEntity(m3uuid,"Magasin3"))
dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m2uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a1uuid,m3uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a2uuid,m1uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m1uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m2uuid))
dao.insert(ArticlesMagasinsCrossRefEntity(a3uuid,m3uuid))
val sb = StringBuilder()
for(mwa in dao.getMWA()) {
sb.append("\nMagasin is ${mwa.magasin.nomMagasin}. ID is ${mwa.magasin.id} it has ${mwa.articles.size} articles. They are:-" )
for (article in mwa.articles) {
sb.append("\n\tArticle is ${article.title} ID is ${article.id}")
}
}
Log.d("DBINFO",sb.toString())
}
日志的输出是:-
D/DBINFO: Magasin is Magasin1. ID is 0f3384ee-6232-423e-b2f1-a12ebdac6487 it has 2 articles. They are:-
Article is Article2 ID is 2729d017-de05-41d2-8de3-8351dfca0a6b
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
Magasin is Magasin2. ID is ba649833-a8ce-4cf2-a1b8-bcab8f7a7d0a it has 2 articles. They are:-
Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19
Magasin is Magasin3. ID is eed6f0a5-0825-4cda-9eb4-c4e973a49738 it has 2 articles. They are:-
Article is Article1 ID is 8763421d-b86d-4725-8e6b-65570958ebdc
Article is Article3 ID is 42057ea7-bc03-409f-b2b8-2dc3fa5def19