首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala/Slick中,如何像这样重构代码(响应拦截)?

在Scala/Slick中,如何像这样重构代码(响应拦截)?
EN

Stack Overflow用户
提问于 2015-03-03 17:51:46
回答 2查看 92关注 0票数 2

代码如下:

代码语言:javascript
复制
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")
}

这些代码出现了很多次,真的很烦人

代码语言:javascript
复制
   val size = res.size
      if (size <= 1)
        Future(res.headOption.map(userProfileRecordToUserProfile))
      else
        throw new Exception("db error")

有没有人有在Slick中重构它的想法?

EN

回答 2

Stack Overflow用户

发布于 2015-03-03 18:11:24

你可以很容易地在这里使用高阶函数,首先让我们把你的查询从方法中去掉:

代码语言:javascript
复制
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)

请注意,我之所以将其设置为惰性,是因为您在作用域中还没有会话。

现在,让我们创建一个函数来执行这个查询(您可以使用一个type参数使其更加通用):

代码语言:javascript
复制
def executeQuery(q: ⇒ : Query[UserProfiles, UserProfiles#TableElementType]): Int = {
  db.withSession { implicit session ⇒
    q.list
  }
}

然后我们需要检查长度:

代码语言:javascript
复制
def listToUserProfile(list: List[UserProfile]): Future[Option[UserProfile]] = {
  if (list.length <= 1)
    Future(list.headOption.map(userProfileRecordToUserProfile))
  else
     throw new Exception("db error")
}

现在你可以这样做了:

代码语言:javascript
复制
listToUserProfile(executeQuery(a))

可能有一些错误,因为你的代码不可运行,我也不能编译它。

票数 1
EN

Stack Overflow用户

发布于 2015-03-03 18:30:05

首先,创建一个泛型方法来执行查询,该方法使用Either返回将来或错误

代码语言:javascript
复制
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"))
       }
    }
  }

现在在代码中,您可以简单地执行以下操作

代码语言:javascript
复制
def find(loginInfo: LoginInfo): Future[Option[UserProfile]] = 
      getElement(userProfileTable.filter(u => u.userName === loginInfo.providerKey)).right.map(userProfileRecordToUserProfile)

对其他人也是如此:

代码语言:javascript
复制
def findByEmail(loginInfo: LoginInfo): Future[Option[UserProfile]] = 
      getElement( userProfileTable.filter(u => u.email === email && u.status === 1))).right.map(userProfileRecordToUserProfile)

顺便说一句,您不是在DB调用上包装future,而是在获得结果之后。DB调用将是阻塞的主要来源,而不是DB结果的处理。您应该考虑在将来包装DB调用

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28828672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档