【问题标题】:Slick: two queries, one transactionSlick:两个查询,一个事务
【发布时间】:2018-03-02 22:53:41
【问题描述】:

假设我有两张桌子:

people:

id: long | uuid: UUID     | name: String

----

cars

id: long | owner_id: long | name: String

其中ownerpeople.id 的外键。

我有一个查询,根据车主的 uuid(只是一个 API 设计)选择所有车主。

问题是:如何在一个事务中执行以下查询,我必须通过其uuid (SELECT id from people where uuid = ?) 和SELECT * from cars where owner_id = id 获取people.id

当然,我一开始可以通过uuidpeople表中获取id,比如

val ownerId = db run people.filter(_.uuid === uuid.bind).map(_.id).result.head

然后运行另一个查询以通过owner_id 选择汽车:

val cars = ownerId.flatMap { 
  id => db run cars.filter(_.ownerId === id).result 
}

但这不会发生在一笔交易中。有什么想法吗?

【问题讨论】:

    标签: scala transactions slick


    【解决方案1】:

    有一个transactionally 方法用于巧妙的操作。你应该使用:

    import slick.driver.PostgresDriver.api._  // for example
    
    val query = for {
      p <- peoples.filter(_.uuid === "some-id")
      c <- cars.filter(_.owner_id === p.uuid)
    } yield (p, c)
    
    val action = query.result
    val transactionalAction = action.transactionally // will be executed 
                                                     // in single transaction
    
    // Ungrouped result
    // TODO: You can group on db side by your query or 
    // on client side using groupBy from collection API
    val result:Future[Seq[(People, Cars)]] = db.run(transactionalAction)
    

    【讨论】:

      【解决方案2】:

      我会说:

      val groupByQuery =  cars.join(people)
       .on (_.owner_id === _.id)
       .map{
        case (car, owner) => (owner.uuid, car)
       }
      .groupBy(_._1)
      
      db.run(groupByQuery)
      

      【讨论】:

        猜你喜欢
        • 2016-02-07
        • 2011-06-19
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多