Future 和 Option 在 slick 中的理解
Future and Option in for comprehension in slick
我在使用 slick 方面还很陌生,现在我遇到了如何从两个 table 中检索一些数据的问题。
我有一个 table
class ExecutionTable(tag: Tag) extends Table[ExecTuple](tag, "execution") {
val id: Rep[String] = column[String]("id")
val executionDefinitionId: Rep[Long] = column[Long]("executionDefinitionId")
// other fields are omitted
def * = ???
}
还有一个table
class ServiceStatusTable(tag: Tag)
extends Table[(String, Option[String])](tag, "serviceStatus") {
def serviceId: Rep[String] = column[String]("serviceId")
def detail: Rep[String] = column[String]("detail")
def * = (serviceId, detail.?)
}
在 Dao 中,我将这两个 table 中的数据转换为业务对象
case class ServiceStatus(
id: String,
detail: Option[String] = None, //other fields
)
像这样
private lazy val getServiceStatusCompiled = Compiled {
(id: Rep[String], tenantId: Rep[String]) =>
for {
exec <- getExecutionById(id, tenantId)
status <- serviceStatuses if exec.id === status.serviceId
} yield mapToServiceStatus(exec, status)
}
以后
def getServiceStatus(id: String, tenantId: String)
: Future[Option[ServiceStatus]] = db
.run(getServiceStatusCompiled(id, tenantId).result.transactionally)
.map(_.headOption)
问题是并非 table execution
中的所有条目都存在 table serviceStatus
中的条目。我无法修改 table execution
并向其添加字段 details
,因为它仅特定于服务。
当我 运行 查询以防 execution
中的条目存在 serviceStatus
中的条目时,所有工作都按预期进行。但如果 serviceStatus
中没有条目,则返回 Future[None]。
问题:是否有任何选项可以根据 table serviceStatus
中的现有条目或其他一些解决方法来获取 status
以作为选项进行理解?
通常,如果连接条件在 "right" table 中找不到相应的记录,但结果仍应包含来自 "left" table 的行,left加入被使用。
在您的情况下,您可以执行以下操作:
Execution
.filter(...execution table filter...)
.joinLeft(ServiceStatus).on(_.id===_.serviceId)
这给你一对
(Execution, Rep[Option[ServiceStatus]])
查询执行后:
(Execution, Option[ServiceStatus])
我在使用 slick 方面还很陌生,现在我遇到了如何从两个 table 中检索一些数据的问题。 我有一个 table
class ExecutionTable(tag: Tag) extends Table[ExecTuple](tag, "execution") {
val id: Rep[String] = column[String]("id")
val executionDefinitionId: Rep[Long] = column[Long]("executionDefinitionId")
// other fields are omitted
def * = ???
}
还有一个table
class ServiceStatusTable(tag: Tag)
extends Table[(String, Option[String])](tag, "serviceStatus") {
def serviceId: Rep[String] = column[String]("serviceId")
def detail: Rep[String] = column[String]("detail")
def * = (serviceId, detail.?)
}
在 Dao 中,我将这两个 table 中的数据转换为业务对象
case class ServiceStatus(
id: String,
detail: Option[String] = None, //other fields
)
像这样
private lazy val getServiceStatusCompiled = Compiled {
(id: Rep[String], tenantId: Rep[String]) =>
for {
exec <- getExecutionById(id, tenantId)
status <- serviceStatuses if exec.id === status.serviceId
} yield mapToServiceStatus(exec, status)
}
以后
def getServiceStatus(id: String, tenantId: String)
: Future[Option[ServiceStatus]] = db
.run(getServiceStatusCompiled(id, tenantId).result.transactionally)
.map(_.headOption)
问题是并非 table execution
中的所有条目都存在 table serviceStatus
中的条目。我无法修改 table execution
并向其添加字段 details
,因为它仅特定于服务。
当我 运行 查询以防 execution
中的条目存在 serviceStatus
中的条目时,所有工作都按预期进行。但如果 serviceStatus
中没有条目,则返回 Future[None]。
问题:是否有任何选项可以根据 table serviceStatus
中的现有条目或其他一些解决方法来获取 status
以作为选项进行理解?
通常,如果连接条件在 "right" table 中找不到相应的记录,但结果仍应包含来自 "left" table 的行,left加入被使用。 在您的情况下,您可以执行以下操作:
Execution
.filter(...execution table filter...)
.joinLeft(ServiceStatus).on(_.id===_.serviceId)
这给你一对
(Execution, Rep[Option[ServiceStatus]])
查询执行后:
(Execution, Option[ServiceStatus])