【问题标题】:Two joins with same table with Slick 3.0使用 Slick 3.0 连接同一张表的两个连接
【发布时间】:2023-03-22 15:57:02
【问题描述】:

我正在尝试使用 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)

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

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

谢谢!

塞尔吉

【问题讨论】:

    标签: mysql scala slick slick-3.0


    【解决方案1】:

    在 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 理解在一个单子连接中组合了三个查询。您可以更进一步,并在另一个数据库查询中重用 query 等等。实际上,当我将 Conversation 映射到它的 id (query.map(_.conversationId)) 时,我就是这样做的。

    刚开始时 Slick 有点难以掌握,尤其是当您习惯了像 Hibernate 这样的 ORM 时,但我希望您掌握了大致的概念。

    【讨论】:

    • 谢谢你我已经以其他方式完成了(我认为),但我会审查你的解决方案
    【解决方案2】:

    我终于做到了,它成功了: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)
    

    【讨论】:

    • 你明白了 :) 你做了完全相同的事情,只是你的代码比我的更简洁。
    猜你喜欢
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 2016-11-27
    • 2023-02-23
    • 1970-01-01
    • 2015-05-18
    相关资源
    最近更新 更多