0

我需要在数据库中插入一个实体类型的对象

case class Entity(id: Long, name: String)
case class OtherEntity(id: Long, entity_id: Long, info: String)
case class AnotherEntity(other_entity_id: Long, data: String)

如果在输入时我收到大约

{
    "name": "string",
    "data": [
        {
            "info": "string",
            "data": [
                {
                    "data": "string"
                }       
            ]
        }
    ]
}

主要问题是我想不出 doobie.ConnectioIO 的模拟 foreach。

sql"insert into entity (name) values('name')"
    .update.withUniqueGeneratedKeys[Long]("id")
.flatmap(entityId => 
    sql"insert into other_entity (entity_id, info) values ($entityId, 'info')"
        .update.withUniqueGeneratedKeys[Long]("id")
).flatmap(otherEntityId => 
    sql"insert into another_entity (other_entity_id, data) values ($otherEntityId, 'data')"
        .update.run
)

但这仅适用于一对一的关系。感谢您的帮助。

4

1 回答 1

1

您可以将同一外键的多个插入链接在一起。即,如果List每个“名称”都有一个“信息”,则可以遍历该列表以返回一个ConnectionIO[List[_]]. 或者只是一个ConnectionIO[Unit],如果你使用traverse_.

import doobie.implicits._
import cats.implicits._

sql"insert into entity (name) values('name')"
  .update.withUniqueGeneratedKeys[Long]("id")
  .flatMap{ entityId => 
    val infos: List[String] = ???
    infos.traverse_{ info =>
      sql"insert into other_entity (entity_id, info) values ($entityId, $info)"
        .update.withUniqueGeneratedKeys[Long]("id")
        .flatMap{ otherEntityId =>
          val datas: List[String] = ???
          datas.traverse_{ data =>
            sql"insert into another_entity (other_entity_id, data) values ($otherEntityId, $data)"
              .update.run
          }
        }
    }
  }
于 2021-04-28T11:04:53.780 回答