使用 Slick 3.0 的两个具有相同 table 的连接

Two joins with same table with Slick 3.0

我正在尝试使用 Slick 3.0

进行以下 sql 查询
select cm_buyer.conversation_id
from conversations c
inner join conversation_members cm_buyer on cm_buyer.conversation_id = c.id
inner join conversation_members cm_seller on cm_buyer.conversation_id = cm_seller.conversation_id
where (cm_buyer.talker_id = "7LUhaK"
and cm_buyer.is_buyer = 1)
and c.`product_id` = "2"
and (cm_seller.`talker_id` = "BBBBBB" and cm_seller.is_buyer = 0);

我是 Slick 的新手,我从来都不是 mysql 的超级高手,所以我需要一些帮助。如您所见,我正在从会话 table 到同一个 table conversation_members.

进行两次连接

我在做类似的事情:

val sellerId = TalkerId("7LUhak")
val buyerId = TalkerId("BBBBBB")
val conversationMembers = TableQuery[ConversationMemberTable]
val conversations = TableQuery[ConversationTable]

val query = for {
  a <- conversations join conversationMembers on (_.id === _.conversationId)
  // SOME MAGIC HERE
} yield (something)

PersistenceUtils.run(query.result)

我已经用这两个 table 查询(添加、简单选择...)完成了一些基本查询,因此映射正确完成。我已经尝试在魔术部分做很多事情但没有运气:(

你能帮我解决这个问题吗?

谢谢!

塞尔吉

在 slick 中,一切都是关于混合和组合查询(未经测试的示例):

val conversationMembers = TableQuery[ConversationMemberTable]
val conversations = TableQuery[ConversationTable]

val sellerQuery = conversationMembers.filter(b => b.talkerId === "7LUhaK" && b.isBuyer === 1)
val buyerQuery = conversationMembers.filter(s => s.talkerId === "BBBBBB" && s.isBuyer === 0)

val query = for {
  c      <- conversations.filter(_.productId === 2)
  buyer  <- buyerQuery if c.id === buyer.conversationId
  seller <- sellerQuery if buyer.conversationId === seller.conversationId
} yield buyer

val action = query.map(_.conversationId).result  // omit .map(...) to fetch the whole model instead
PersistenceUtils.run(action)

如您所见,我使用 for comprehension 将三个查询组合在一个单子连接中。您可以更进一步,在另一个数据库查询中重用 query 等等。实际上,当我将 Conversation 映射到其 id (query.map(_.conversationId)) 时,我就这样做了。

Slick 在开始时有点难以掌握,尤其是当您习惯了 Hibernate 等 ORM 时,但我希望您能掌握总体思路。

我终于做到了并且有效:D

val conversationMembers = TableQuery[ConversationMemberTable]

val query = for {
  c <- conversations if c.productId === productId
  cmBuyer <- conversationMembers if c.id === cmBuyer.conversationId && cmBuyer.talkerId === buyerId && cmBuyer.isBuyer === true
  cmSeller <- conversationMembers if c.id === cmSeller.conversationId && cmSeller.talkerId === sellerId && cmSeller.isBuyer === false
} yield (c)



PersistenceUtils.run(query.result)