为了做到这一点,我们必须使用 DTO 和 DAO 方法......其中数据库模型具有一对多或多对多,当您转换它时,DTO 包含另一个对象的序列并由处理程序,例如:
DTO
case class City(code: String,
lat: Double,
lng: Double,
countryCode: String,
translations: Seq[CityI18n])
case class CityI18n(id: Option[Int], lang: String, name: String)
DAO 和 ROW:
case class CityRow(code: String, lat: Double, lng: Double, countryCode: String)
case class CityI18nRow(id: Int, cityCode: String, lang: String, name: String)
显然,您的映射表和 FK 的实现:
class CityI18nTable(tag: Tag) extends Table[CityI18nRow](tag, "cityi18n") {
//...
def cityCode = column[String]("cityCode", O.Length(TextMaxLength_3))
def cityCodeFK = foreignKey("city_i18n_city_fk", cityCode, Cities)(_.code, onUpdate = ForeignKeyAction.Cascade, onDelete = ForeignKeyAction.Cascade)
//...
}
所以我们在 repo 中构建它:
def find(code: String): Future[Option[City]] = {
val query = for {
city <- Cities if city.code === code
cityI18n <- CityI18ns if city.code === cityI18n.cityCode
} yield (city, cityI18n)
def handler(mainTuples: Seq[(CityRow, CityI18nRow)]) = {
mainTuples.groupBy(_._1).map {
case (cityRow, tuples) =>
val cityI18nRows = tuples.map(_._2).distinct
City(cityRow.code, cityRow.lat, cityRow.lng, cityRow.countryCode, cityI18nRows)
}.headOption
}
db.run(query.result).map(handler)
}