问题描述
R2DBC 目前不支持复合键。我想知道我们现在如何实现多对多关系?
例如,给定两个实体:
@Table
class Item(
@Id var id: Long?,var title: String,var description: String,)
@Table
class Tag(
@Id
var id: Long?,var color: String,)
及其架构:
CREATE TABLE item (
id SERIAL PRIMARY KEY NOT NULL,title varchar(100) NOT NULL,description varchar(500) NOT NULL
);
CREATE TABLE tag (
id SERIAL PRIMARY KEY NOT NULL,color varchar(6) NOT NULL
);
我可以为多对多映射创建一个表:
CREATE TABLE item_tag (
item_id bigint NOT NULL,tag_id bigint NOT NULL,PRIMARY KEY(item_id,tag_id)
);
但是我们应该如何在 kotlin/java 中定义映射类 ItemTag
?
@Table
class ItemTag(
// ??????????????????????? @Id ?????????????????????
var itemId: Long,var tagId: Long,)
还是可以省略 @Id
?那么该类不能有任何 Repository
吗?我想这样就好了。这是唯一的含义吗?
解决方法
可能还有其他方法可以做到这一点。由于 CompositeKey
尚不支持 R2DBC
我认为。因此,这只是解决您问题的一种方法。
数据类
data class ItemTag(val itemId: Long,val tagId: Long)
然后是存储库
interface TagRepository {
fun getItemTagByTagId(tagId: Long): Flow<ItemTag>
}
Repository 实现
@Repository
class TagRepositoryImpl(private val databaseClient: DatabaseClient) : TagRepository {
override fun getItemTagByTagId(tagId: Long): Flow<ItemTag> {
return databaseClient.sql("SELECT * FROM item_tag WHERE tag_id = :tagId")
.bind("tagId",tagId)
.map(row,_ -> rowToItemTag(row))
.all()
.flow()
}
private fun rowToItemTag(row: Row): ItemTag {
return ItemTag(row.get("item_id",Long::class.java)!!,row.get("tag_id",Long::class.java)!!)
}
}
类似的东西。