【发布时间】:2016-08-24 10:32:46
【问题描述】:
此代码正在创建一个查询,用于在 Web 后端检索用户的个人资料。它创建一个查询,将必要的信息组装成一个 DTO(它只是一个案例类),随后以 JSON 的形式发回。
def getProfile(userId: Long)={
val q = for{
((((u,p),a),b), ba) <- filterById(userId) join
People on (_.personId === _.id) joinLeft
Addresses on (_._2.addressId === _.id) joinLeft
Businesses on (_._1._2.businessId === _.id) joinLeft
Addresses on (_._2.flatMap(_.addressId) === _.id)
}yield(p, a, b, ba)
db.run(q.result.headOption).map{ _.map{case(p,a,b,ba) =>
val business = b match {
case Some(b) => Some(dtos.Business(b.name, b.abn, b.adminFee, ba, b.id))
case _ => None
}
dtos.ProfileInfo(p, a, business)
}}
}
我已将结果处理 (db.run(...)) 仅用于上下文。
我正在寻找一种更易读的方式来表达查询结构。
我的阅读体验是“等等,什么??...on (_._1._2.flatMap(_.addressId) ....这是在做什么??为什么 flatmap 在那里而不是在这里:on (_._1._2.businessId。这些实际上是直截了当的事情,但不要完全不直接阅读。
我正在寻找一种表达方式,不需要阅读此版本所需的扣除量。我必须“推断”什么是_._1._2,以及为什么需要将其展平,这与等效的SQL无关。
注意事项:
- 此代码来自我正在扩展的现有应用程序(不是我编写的)。
- 用户、人员、地址、企业是(显然?)表格。
- 人和企业都有地址。
- 用户有一个人(*),人有一个企业
-
filterByUserId(userId)基本等同于Users.filter(_.id === userId) -
等效的 SQL 是:
select p.*, a1.*, b.*, a2.* from Users u innerJoin People p on (u.personId == p.id) leftJoin Addresses a1 on (p.addressId == a1.id) leftJoin Businesses b on (p.businessId == b.id) leftJoin Addresses a2 on ( b.addressId == a2.id)
【问题讨论】:
-
我很乐意用简洁换取可读性。我一直在寻找以增量方式编写查询的方法,但看不到如何。我想摆脱 LHS 上的嵌套元组和 RHS 上的嵌套 .。