以下是代码:
def find(loginInfo: LoginInfo): Future[Option[UserProfile]] = {
val res = DB.withSession { implicit session =>
//if loginInfo.providerID == "waylens"
userProfileTable.filter(u => u.userName === loginInfo.providerKey).list
}
val size = res.size
if (size <= 1)
Future(res.headOption.map(userProfileRecordToUserProfile))
else
throw new Exception("db error")
}
def findByEmail(providerID: String, email: String): Future[Option[UserProfile]] = {
val res = DB.withSession { implicit session =>
//if loginInfo.providerID == "waylens"
userProfileTable.filter(u => u.email === email && u.status === 1).list
}
val size = res.size
if (size <= 1)
Future(res.headOption.map(userProfileRecordToUserProfile))
else
throw new Exception("db error")
}
def findByProfileID(profileID: Long): Future[Option[UserProfile]] = {
val res = DB.withSession { implicit session =>
userProfileTable.filter(u => u.id === profileID).list
}
val size = res.size
if (size <= 1)
Future(res.headOption.map(userProfileRecordToUserProfile))
else
throw new Exception("db error")
}
这些代码多次出现,这真的很烦人
val size = res.size
if (size <= 1)
Future(res.headOption.map(userProfileRecordToUserProfile))
else
throw new Exception("db error")
有没有人有关于在Slick中重构这个的想法?
答案 0 :(得分:1)
您可以在这里轻松使用高阶函数,首先让我们从方法中获取您的查询:
lazy val a = userProfileTable.filter(u => u.userName === loginInfo.providerKey)
lazy val b = userProfileTable.filter(u => u.email === email && u.status === 1)
lazy val c = userProfileTable.filter(u => u.id === profileID)
请注意,我正在使这个懒惰,因为你还没有在范围内进行会话。
现在让我们创建一个执行此查询的函数(您可以使用类型参数使其更通用):
def executeQuery(q: ⇒ : Query[UserProfiles, UserProfiles#TableElementType]): Int = {
db.withSession { implicit session ⇒
q.list
}
}
然后我们需要检查长度:
def listToUserProfile(list: List[UserProfile]): Future[Option[UserProfile]] = {
if (list.length <= 1)
Future(list.headOption.map(userProfileRecordToUserProfile))
else
throw new Exception("db error")
}
现在你可以这样做:
listToUserProfile(executeQuery(a))
可能存在一些错误,因为您的代码无法运行,我无法编译它。
答案 1 :(得分:1)
首先使用Either
创建一个通用方法来执行返回未来或错误的查询
def getElement[E, U, C[_]](query: Query[E, U, C]) = {
db.withSession { implicit session =>
query.list.headOption match {
case Some(ele) => Right(Future(ele))
case None => Left(new Exception("db error"))
}
}
}
现在在代码中,你可以做到
def find(loginInfo: LoginInfo): Future[Option[UserProfile]] =
getElement(userProfileTable.filter(u => u.userName === loginInfo.providerKey)).right.map(userProfileRecordToUserProfile)
与其他人类似:
def findByEmail(loginInfo: LoginInfo): Future[Option[UserProfile]] =
getElement( userProfileTable.filter(u => u.email === email && u.status === 1))).right.map(userProfileRecordToUserProfile)
另一方面,您没有将future
包裹在数据库调用之上但是在获得结果之后。数据库调用将是阻塞的主要来源,而不是数据库结果的处理。您应该考虑在未来包装数据库调用