【问题标题】:slick returning a dictionaries object from database光滑从数据库返回一个字典对象
【发布时间】:2017-10-03 18:27:47
【问题描述】:

我正在尝试从几个表中进行选择并将它们的结果放入一个对象中。我想这样做是因为这些是字典,我希望在启动时全部使用它们。

这就是我现在拥有的:

控制器:

  def getDictionaries = Action.async { implicit request =>
    Future.successful(Ok(Json.toJson(dictionaryService.getDictionaries)))
  }

字典服务:

  override def getDictionaries : Dictionaries = {
    val currencies: Future[Seq[Currency]] = dictionaryDao.getCurrencies
    val propertyTypes: Future[Seq[PropertyType]] = dictionaryDao.getPropertyTypes
    Dictionaries(
      currencies.result(Duration(10L, TimeUnit.SECONDS)),
      propertyTypes.result(Duration(10L, TimeUnit.SECONDS))
    )
  }

字典DAO:

  override def getCurrencies: Future[Seq[Currency]] = {
    db.run(slickCurrencies.result)
  }
  ... getPropertyTypes ...

字典案例类和伴随对象

case class Dictionaries (currencies: Seq[Currency], propertyTypes: Seq[PropertyType])

object Dictionaries {
  implicit val jsonFormat = Json.format[Dictionaries]
}

我对@9​​87654325@ 不是很自豪,但我不确定我应该从这个函数中检索什么,以便可以轻松地将其转换为 JSON。此外,这行代码仍然无法正常工作,因为编译器告诉我改用 Await 对象。

对于 PropertyType,我也需要对货币做同样的事情。

获得预期结果的最佳方法是什么?

我正处于学习阶段,所以我对此了解不多。

后期编辑:流程是:request -> getDictionaries -> dictionaryService.getDictionaries -> dictionaryDAO.getCurrencies&PropertyTypes

在我看来,我需要以同步的方式获取它们。

这样做的目的是不为每种类型的字典创建请求。如果我有 10 个字典,我想在一个请求中获取所有字典。

稍后编辑 2

这是我的工作示例,看起来不太好:

控制器:

  def getDictionaries = Action.async { implicit request =>
    dictionaryService.getDictionaries.map {
      dictionaries => Ok(Json.toJson(dictionaries))
    }
  }

字典服务:

  override def getDictionaries : Future[Dictionaries] = {
    dictionaryDao.getCurrencies.flatMap { currencies =>
      dictionaryDao.getPropertyTypes.flatMap { propertyTypes =>
        Future.successful(Dictionaries(
          currencies,
          propertyTypes
        ))
      }
    }
  }

【问题讨论】:

    标签: scala playframework slick


    【解决方案1】:

    您的方法getDictionaries 应该返回Future[Dictionaries]

    override def getDictionaries : Future[Dictionaries] = {
        val futureCurrencies = dictionaryDao.getCurrencies
        futureCurrencies map { currencies => // currencies is here Seq[Currency]
          Dictionaries(
            currencies,
            List(PropertyType(1, "x"))
        )
      }
    

    还有你的控制器方法:

    def getDictionaries = Action.async { implicit request =>
        val futureDictionaries = dictionaryService.getDictionaries
        futureDictionaries map { dictionaries =>
          Ok(Json.toJson(dictionaries))
        }
    }
    

    解释:如果您希望您的操作真正异步,则必须自下而上使用Futures。您必须学习如何使用mapflatMapfor comprehensions 组合它们。我没有找到任何温和而简短的介绍,你必须自己搜索它。基本上,当您 map 超过 Future 时,您正在转换它的(成功)结果,从而获得另一个 Future。使用flatMap,您可以对期货进行一些排序,例如:当f1 完成时,开始f2 等...

    【讨论】:

    • 这真的有效吗,因为我正在将一个带有未来的对象转换为 json。这会被正确转换吗?据我了解,您的解决方案是告诉我在我的字典对象中存储一些字典的未来。
    • 是的,如果您希望您的操作确实是异步的,您需要将未来一直传播到控制器。您的解决方案是一半,当您调用此行时:currencies.result(Duration(10L, TimeUnit.SECONDS)) 您实际上阻塞了您的线程,等待未来的终止。
    • 我感觉你误会了我。我更新了我的代码,请看一下。
    • 最后我还加了一些解释。
    • 我设法让它工作,但我对结果并不十分自豪。请看一看。
    猜你喜欢
    • 2014-03-18
    • 2023-03-14
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    相关资源
    最近更新 更多