Play框架和Slick自动数据库创建

2024-03-16

我正在使用 play 2.4 和 Slick 3,是否可以自动生成 ddl 脚本,它是进化吗?

在官方文档中我找到了一些脚本,但是我应该将其放在播放框架中的哪里?http://slick.typesafe.com/doc/3.1.0/schemas.html http://slick.typesafe.com/doc/3.1.0/schemas.html

你知道有什么库可以管理代码的演变而不是编写简单的 SQL 吗?


我使用 PostgresDriver 做了一些解决方法,我创建了将 DDL 打印到文件的模块。每次代码更改后,我只需要替换 1.sql 或稍后修改下一个演变脚本:

计算机数据库模块.scala

package bootstrap

import com.google.inject.AbstractModule
import play.api.{Mode, Play}

class ComputersDatabaseModule extends AbstractModule {

  protected def configure() = {
    bind(classOf[CreateDDL]).asEagerSingleton()
    bind(classOf[InitialData]).asEagerSingleton()
  }
}

创建DDL.scala

package bootstrap

import java.io.PrintWriter
import javax.inject.Inject

import dao.{CompaniesMapping, ComputersMapping}
import play.api.db.slick.{HasDatabaseConfigProvider, DatabaseConfigProvider}
import slick.driver.JdbcProfile


/**
  * Creates DDL script
  */
private[bootstrap] class CreateDDL @Inject()(protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with
  ComputersMapping with CompaniesMapping {

  def createDDLScript() = {
    import slick.driver.PostgresDriver.api._

    val allSchemas = companies.schema ++ computers.schema

    val writer = new PrintWriter("target/migration_ddl.sql")
    writer.write("# --- !Ups\n\n")
    allSchemas.createStatements.foreach { s => writer.write(s + ";\n") }

    writer.write("\n\n# --- !Downs\n\n")
    allSchemas.dropStatements.foreach { s => writer.write(s + ";\n") }

    writer.close()
  }

  createDDLScript()
}

计算机DAO.scala

package dao

import java.util.Date
import javax.inject.{Inject, Singleton}
import models.{Company, Computer, Page}
import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import slick.driver.JdbcProfile

import scala.concurrent.Future

trait ComputersMapping { self: HasDatabaseConfigProvider[JdbcProfile] =>
  import driver.api._

  class Computers(tag: Tag) extends Table[Computer](tag, "COMPUTER") {

    implicit val dateColumnType = MappedColumnType.base[Date, Long](d => d.getTime, d => new Date(d))

    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
    def name = column[String]("NAME")
    def introduced = column[Option[Date]]("INTRODUCED")
    def discontinued = column[Option[Date]]("DISCONTINUED")
    def companyId = column[Option[Long]]("COMPANY_ID")

    def * = (id.?, name, introduced, discontinued, companyId) <> (Computer.tupled, Computer.unapply)
  }

  val computers = TableQuery[Computers]
}

@Singleton()
class ComputersDAO @Inject() (protected val dbConfigProvider: DatabaseConfigProvider) extends CompaniesMapping with ComputersMapping
  with HasDatabaseConfigProvider[JdbcProfile] {
  import driver.api._

  /** Retrieve a computer from the id. */
  def findById(id: Long): Future[Option[Computer]] =
    db.run(computers.filter(_.id === id).result.headOption)

  /** Count all computers. */
  def count(): Future[Int] = {
    // this should be changed to
    // db.run(computers.length.result)
    // when https://github.com/slick/slick/issues/1237 is fixed
    db.run(computers.map(_.id).length.result)
  }
  /** Count computers with a filter. */
  def count(filter: String): Future[Int] = {
    db.run(computers.filter { computer => computer.name.toLowerCase like filter.toLowerCase }.length.result)
  }

  /** Return a page of (Computer,Company) */
  def list(page: Int = 0, pageSize: Int = 10, orderBy: Int = 1, filter: String = "%"): Future[Page[(Computer, Company)]] = {

    val offset = pageSize * page
    val query =
      (for {
        (computer, company) <- computers joinLeft companies on (_.companyId === _.id)
        if computer.name.toLowerCase like filter.toLowerCase
      } yield (computer, company.map(_.id), company.map(_.name)))
        .drop(offset)
        .take(pageSize)

    for {
      totalRows <- count(filter)
      list = query.result.map { rows => rows.collect { case (computer, id, Some(name)) => (computer, Company(id, name)) } }
      result <- db.run(list)
    } yield Page(result, page, offset, totalRows)
  }

  /** Insert a new computer. */
  def insert(computer: Computer): Future[Unit] =
    db.run(computers += computer).map(_ => ())

  /** Insert new computers. */
  def insert(computers: Seq[Computer]): Future[Unit] =
    db.run(this.computers ++= computers).map(_ => ())

  /** Update a computer. */
  def update(id: Long, computer: Computer): Future[Unit] = {
    val computerToUpdate: Computer = computer.copy(Some(id))
    db.run(computers.filter(_.id === id).update(computerToUpdate)).map(_ => ())
  }

  /** Delete a computer. */
  def delete(id: Long): Future[Unit] =
    db.run(computers.filter(_.id === id).delete).map(_ => ())

}

添加配置(应用程序配置):

play.modules.enabled += "bootstrap.ComputersDatabaseModule"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Play框架和Slick自动数据库创建 的相关文章

随机推荐

  • FontAwesome Icons 仅在鼠标悬停时旋转?

    在很棒的字体中 我如何使用此代码 i class fa fa spinner fa spin i 仅适用于鼠标悬停 您也可以创建另一个仅用于悬停的类 而不是覆盖该类 fa spin hover hover webkit animation
  • TypeScript 中的扩展如何工作?

    以下 TypeScript 代码 class BaseClassWithConstructor private id number constructor id number this id id class DerivedClassWit
  • 随机数,Math.floor(...) 与 Math.ceil(...)

    我见过很多生成随机数的代码 例如 random integers in the interval 1 10 Math floor Math random 10 1 无论如何 我感觉我失去了一些东西 为什么人们不使用更简洁的方式 Math c
  • 是否可以用符合特定条件的行号填充数组而不循环?

    我想用仅满足特定条件的行的行号填充VBA中的数组 我想要尽可能最快的方法 例如 类似RowArray index valRange valMatch row 下面是 慢速 范围循环的代码 Current Code Sub get row n
  • 构建带有递归函数的.so

    在处理一些项目期间 我遇到了无法构建so库的问题 我收到如下错误 创建共享对象时 不能使用针对符号 的重定位 R X86 64 PC32 使用 fPIC 重新编译最终我设法找到了根本原因 这是库中的递归函数 例如 我有以下众所周知的例子 s
  • Django Channels 错误:您不能在与异步事件循环相同的线程中使用 AsyncToSync

    我试图复制 Django Channels Documentation 中的教程 但我有错误 它说 您不能在与异步事件循环相同的线程中使用 AsyncToSync 只需直接等待异步函数 信息 WebSocket 握手 ws notifica
  • 与从 Cloud Console 创建的项目相比,从 App Engine 控制台创建的项目的功能较少

    当我从 App Engine 控制台创建新应用程序时https appengine google com https appengine google com 该应用程序也会出现在 Cloud Console 上https cloud go
  • 通过套接字获取线路

    是否有一个 libc 函数可以执行与 getline 相同的操作 但可以使用连接的套接字而不是 FILE 流 解决方法是在套接字上调用 fdopen 这样做的时候需要注意哪些事项 这样做 不这样做的理由是什么 这样做的一个明显原因是调用 g
  • 判断表单输入是否有焦点

    我正在 AngularJS 中进行验证 如果有 3 种类型的错误 我会显示一个 div 对于必需的 我只想在页面以空值提交时才显示错误消息 div class error div 对于正则表达式验证 我希望它标记实时的默认行为 div cl
  • jquery onclick 添加左边距

    我正在尝试用 JS 做一些非常简单的事情 但我无法让它工作 我想当点击div添加一个负数margin left到另一个div 但我希望每次点击时都会发生div 而不是像现在这样一次 每次我点击我的 next nav 我想要 nav移动自 1
  • 使用 Devise 注销所有用户

    我在 ruby on rails 应用程序中使用 devise 我有一个使用设备的 User 类和 AdminUser 类 在我的管理面板中 我想注销所有用户 但不注销管理员用户 执行此操作的最佳方法是使用范围级别的注销方法 因此 如果您想
  • TransactionAttribute 注释 (@REQUIRES_NEW) 被忽略

    我遇到了两个单独的事务的问题 这些事务以与实际执行的顺序相反的顺序刷新到数据库 这是业务案例 存在 RemoteJob RemoteJobEvent 一对多关系 每次创建新事件时 都会获取一个时间戳 并将其设置在RemoteJob和Remo
  • 编译器如何知道在哪里可以找到#include

    我想知道 Mac OS X Windows 和 Linux 上的编译器如何知道在哪里可以找到 C 头文件 具体来说 我想知道它如何知道在哪里可以找到带有 lt gt 括号 include Users Brock Desktop Myfile
  • 嵌入式Linux中UART上的9位协议

    我正在尝试在嵌入式 Linux 中的 UART 上强制使用 9 位协议 目前我正在 am335x evm 板上对此进行测试 我计划使用坚持平价来做到这一点 理想情况下 我希望不需要实际修改 omap serial c 驱动程序的任何代码 9
  • 如何将用户从控制台的输入读取为 Unicode 字符串?

    一个C 初学者的问题 这是我目前拥有的 From tchar h define T x T x From tchar h define T x L x In MySampleCode h ifdef UNICODE define tcout
  • AUGraph 弃用是否意味着不再有音频渲染回调?

    我有一个带有详细渲染回调的应用程序 我怀疑是否可以使用 AVAudioEngine 来实现 无论如何 要将我的 AUGraph 渲染回调 具有多个总线 与 AVAudioEngine 一起使用吗 有示例代码吗 The 音频单元API htt
  • Dart 是否有 socket.io 端口?

    我使用这个简单的示例了解了 Dart 中的基本 websocket 功能 https github com financeCoding chat websocket dart https github com financeCoding c
  • 在Java程序中执行PowerShell命令

    我有一个PowerShell Command我需要使用它来执行Java程序 有人可以指导我如何做到这一点吗 我的命令是Get ItemProperty HKLM Software Wow6432Node Microsoft Windows
  • 以编程方式打开/关闭 WiFi 热点

    我需要帮助创建一个在热点模式下设置 Android WiFi 的 C 脚本 这是我设法创建的代码 public bool setAPEnabled bool enabled using AndroidJavaObject activity
  • Play框架和Slick自动数据库创建

    我正在使用 play 2 4 和 Slick 3 是否可以自动生成 ddl 脚本 它是进化吗 在官方文档中我找到了一些脚本 但是我应该将其放在播放框架中的哪里 http slick typesafe com doc 3 1 0 schema