与Slick 3.0相同的两个表连接

时间:2016-01-14 19:38:51

标签: mysql scala slick 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中的超级破解,所以我需要一些帮助。正如您所看到的,我正在从对话表到同一个对话表进行两次连接。

我做了类似的事情:

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)

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

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

谢谢!

塞吉

2 个答案:

答案 0 :(得分:1)

简而言之,它是关于混合和组合查询(未经测试的例子):

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在monadic join中组合了三个查询。您可以更进一步,并在另一个数据库查询中重用query,依此类推。实际上,当我将Conversation映射到其ID(query.map(_.conversationId))时,我就这样做了。

Slick在开始时有点难以理解,特别是当你习惯于像Hibernate这样的ORM时,我希望你能掌握一般的想法。

答案 1 :(得分:1)

我终于做到了这一点并且有效: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)