【问题标题】:How to fetch records from the database using Play with Scala and Slick如何使用 Play with Scala 和 Slick 从数据库中获取记录
【发布时间】:2015-10-05 22:47:50
【问题描述】:

我刚开始使用 Play 框架和 Scala。

为了习惯它,我正在开发一个歌词网络应用程序,但是我在从数据库中获取记录时遇到了一些麻烦......

下面是我的 MusicController.scala。我在def show(id: Long) 收到错误消息。我修改了我找到的代码here

我想我需要实现findById(id),对吧?但是哪里?怎么做?

我最近一直在使用 Laravel,我发现很难找到 Play with Scala 的资源和代码示例。在这种情况下,文档有我需要的东西,但我对在哪里以及如何实现 findById(id) 一无所知。我错过了什么吗?

Music.scala

package models

import play.api.libs.json.Json

case class Music(id: Long, title: String, lyrics: String, year: Int)

object Music {
  implicit val musicFormat = Json.format[Music]
}

MusicController.scala

package controllers

import javax.inject.Inject

import dal.MusicRepository
import models.Music
import play.api.data.Form
import play.api.data.Forms._
import play.api.data.validation.Constraints._
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.libs.json.Json
import play.api.mvc._

import scala.concurrent.{Future, ExecutionContext}

class MusicController @Inject()(repo: MusicRepository, val messagesApi: MessagesApi)
                               (implicit ec: ExecutionContext) extends Controller with I18nSupport {

  def index = Action {
    Ok(views.html.musics.index(musicForm))
  }

  def show(id: Long) = Action {
    Music.findById(id).map { music =>
      Ok(views.html.musics.show(music))
    }.getOrElse(NotFound)
  }

  val musicForm: Form[CreateMusicForm] = Form {
    mapping(
      "title" -> nonEmptyText,
      "lyrics" -> nonEmptyText,
      "year" -> number.verifying(min(0))
    )(CreateMusicForm.apply)(CreateMusicForm.unapply)
  }

  def addMusic = Action.async { implicit request =>
    musicForm.bindFromRequest.fold(
      errorForm => {
        Future.successful(Ok(views.html.musics.index(errorForm)))
      },
      music => {
        repo.create(music.title, music.lyrics, music.year).map { _ =>
          Redirect(routes.MusicController.index)
        }
      }
    )
  }

  def getMusics = Action.async {
    repo.list().map { musics =>
      Ok(Json.toJson(musics))
    }
  }

}

case class CreateMusicForm(title: String, lyrics: String, year: Int)

MusicRepository.scala

package dal

import javax.inject.Inject

import models.Music
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile

import scala.concurrent.{Future, ExecutionContext}

class MusicRepository @Inject()(dbConfigProvider: DatabaseConfigProvider)
                               (implicit ec: ExecutionContext) {

  private val dbConfig = dbConfigProvider.get[JdbcProfile]

  import dbConfig._
  import driver.api._

  private class MusicsTable(tag: Tag) extends Table[Music](tag, "musics") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)

    def title = column[String]("title")

    def lyrics = column[String]("lyrics")

    def year = column[Int]("year")

    def * = (id, title, lyrics, year) <>((Music.apply _).tupled, Music.unapply)
  }

  private val musics = TableQuery[MusicsTable]

  def create(title: String, lyrics: String, year: Int): Future[Music] = db.run {
    (musics.map(m => (m.title, m.lyrics, m.year))
      returning musics.map(_.id)

      into ((stuff, id) => Music(id, stuff._1, stuff._2, stuff._3))

      ) +=(title, lyrics, year)
  }

  def list(): Future[Seq[Music]] = db.run {
    musics.result
  }

}

提前谢谢你!

【问题讨论】:

  • 正如错误提示的那样,您可能希望将findById 实现为Music 对象中的一个方法。虽然它听起来像是属于MusicRepository,但考虑到它很可能会从数据库中获取记录......
  • 感谢您的帮助。你是对的,我已经成功地做到了我想要的:) 现在要发布答案

标签: scala playframework slick


【解决方案1】:

我也设法解决了它:

MusicController.scala

  def show(id: Long) = Action.async { implicit request =>
    repo.findById(id).map { music =>
      Ok(views.html.musics.show(music))
    }
  }

MusicRepository.scala

  def findById(id: Long): Future[Music] = db.run {
    musics.filter(_.id === id).result.head
  }

【讨论】:

    猜你喜欢
    • 2018-06-14
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多