如何使用 Play with Scala 和 Slick 从数据库中获取记录
Posted
技术标签:
【中文标题】如何使用 Play with Scala 和 Slick 从数据库中获取记录【英文标题】:How to fetch records from the database using Play with Scala and 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
,但考虑到它很可能会从数据库中获取记录......
感谢您的帮助。你是对的,我已经成功地做到了我想要的:) 现在要发布答案
【参考方案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
【讨论】:
以上是关于如何使用 Play with Scala 和 Slick 从数据库中获取记录的主要内容,如果未能解决你的问题,请参考以下文章
如何将 IntelliJ 与 Play Framework 和 Scala 一起使用