我知道斯卡拉,作为funcional语言,应该从一个共同的面向对象语言,比如Java的工作方式不同,但我敢肯定,必须有包一组在一个单一的交易数据库变化的方式,确保作为原子以及其他所有ACID财产.
正如光滑的文档(http://slick.lightbend.com/doc/3.1.0/dbio.html)中所解释的那样,DBIOAction允许在这样的事务中对db操作进行分组:
val a = (for {
ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result
_ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*)
} yield ()).transactionally
val f: Future[Unit] = db.run(a)
Run Code Online (Sandbox Code Playgroud)
然而,我的使用情况下(和最真实世界的例子,我能想到的),我有一个代码结构和Controller,这暴露了代码为我的REST端点,该控制器调用多个服务和每个服务将委托数据库操作的DAO.
我常用代码结构的一个粗略示例:
class UserController @Inject(userService: UserService) {
def register(userData: UserData) = {
userService.save(userData).map(result => Ok(result))
}
}
class UserService @Inject(userDao: UserDao, addressDao: AddressDao) {
def save(userData: UserData) = {
for {
savedUser <- userDao.save(userData.toUser)
savedAddress <- addressDao.save(userData.addressData.toAddress)
} yield savedUser.copy(address = savedAddress)
}
}
class SlickUserDao {
def save(user: User) = { …
Run Code Online (Sandbox Code Playgroud) 我试图找到一种方法来获得异步before
和after
语句,其中下一个测试用例在测试用例内部的操作完成之前不会运行.就我而言,它是在数据库中创建和删除表
val table = TableQuery[BlockHeaderTable]
val dbConfig: DatabaseConfig[PostgresDriver] = DatabaseConfig.forConfig("databaseUrl")
val database: Database = dbConfig.db
before {
//Awaits need to be used to make sure this is fully executed before the next test case starts
//TODO: Figure out a way to make this asynchronous
Await.result(database.run(table.schema.create), 10.seconds)
}
"BlockHeaderDAO" must "store a blockheader in the database, then read it from the database" in {
//...
}
it must "delete a block header in the database" in { …
Run Code Online (Sandbox Code Playgroud) 我有一个Scala编译错误我一直无法找到任何信息.我正在使用光滑的3.0,并得到编译错误
value ~ is not a member of slick.lifted.Rep[Option[Int]]
我相信这个问题与我使用Option代表我的ID字段的方式有关.
我已尝试id.?
按照此答案中的建议添加到id字段,但我仍然以同样的方式得到编译错误.光滑3.0有什么变化吗?
我的代码如下:
import slick.driver.H2Driver.api._
import scala.concurrent.ExecutionContext.Implicits.global
case class Recipe(id: Option[Int] = None, name: String, instructions: String, ingredients: String)
object AddFixtures {
class Recipes(tag: Tag) extends Table[Recipe](tag, "recipe") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def instructions = column[String]("instructions")
def ingredients = column[String]("ingredients")
def * = id ~ name ~ instructions ~ ingredients <> (Recipe, Recipe.unapply _)
}
val recipes = TableQuery[Recipes]
val …
Run Code Online (Sandbox Code Playgroud) 我有以下postgres列定义:
record_time TIMESTAMP WITHOUT TIME ZONE DEFAULT now()
Run Code Online (Sandbox Code Playgroud)
我如何将其映射到光滑?请考虑我希望映射now()
函数生成的默认值
即:
def recordTimestamp: Rep[Date] = column[Date]("record_time", ...???...)
Run Code Online (Sandbox Code Playgroud)
是否应该将任何额外的定义放在...???...
当前所在的位置?
编辑(1)
我不想用
column[Date]("record_time", O.Default(new Date(System.currentTimeMillis()))) // or some such applicative generation of the date column value
Run Code Online (Sandbox Code Playgroud) 是否可以更新变量列列表,这个数字仅在运行时通过光滑3.0知道?
下面是我想做的例子(不会编译)
var q: Query[UserTable, UserTable#TableElementType, Seq] = userTable
var columns = List[Any]()
var values = List[Any]()
if (updateCommands.name.isDefined) {
columns = q.name :: columns
values = updateCommands.name.get :: values
}
if (updateCommands.surname.isDefined) {
columns = q.surname :: columns
values = updateCommands.surname.get :: values
}
q = q.filter(_.id === updateCommands.id).map(columns).update(values)
Run Code Online (Sandbox Code Playgroud) 这个问题与另一个问题有关.我也尝试使用joinLeft对查询进行排序,但是在光滑的3.0.0中.随着Option Rep被自动解除,我将如何做同样的事情?:
def list(filter: String, orderBy: Int):Future[Seq[(Computer, Option[Company])]] = {
val initialQuery = for {
(computer, company) <- Computer.filter(_.name like filter) leftJoin
Company on (_.companyId === _.id)
} yield (computer, company)
val sortedQuery = orderBy match {
case 2 => initialQuery.sortBy(_._1.name) //Works ok, column from a primary table
case 3 => initialQuery.sortBy(_._2.map(_.name)) //could not find implicit value for parameter ol: slick.lifted.OptionLift[slick.lifted.ColumnOrdered[String],slick.lifted.Rep[Option[QO]]]
}
db.run(sortedQuery.result)
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
使用Slick 3.1,如何将多个查询组合成同一类型的单个查询?这不是连接或联合,而是组合查询"段"以创建单个查询请求.这些"段"可以是任何单独有效的查询.
val query = TableQuery[SomeThingValid]
// build up pieces of the query in various parts of the application logic
val q1 = query.filter(_.value > 10)
val q2 = query.filter(_.value < 40)
val q3 = query.sortBy(_.date.desc)
val q4 = query.take(5)
// how to combine these into a single query ?
val finalQ = ??? q1 q2 q3 q4 ???
// in order to run in a single request
val result = DB.connection.run(finalQ.result)
Run Code Online (Sandbox Code Playgroud)
编辑:预期的SQL应该是这样的:
SELECT * FROM "SomeThingValid" WHERE …
Run Code Online (Sandbox Code Playgroud) 我有类GroupTable,它可以生成表的模式.
正如我所看到的,在其他项目中有conf/evolution/default文件夹文件1.sql,它是从代码自动生成的(我假设).
但是当我启动我的应用程序时 - 什么都没有创
我该怎么办?是自动创建还是我在代码中编写它?
class GroupTable(tag: Tag) extends Table[Group](tag, "groups") {
def name = column[String]("name", O.PrimaryKey)
def day = column[String]("day")
def subject = column[String]("subject")
def typeSub = column[String]("typeSub")
def start = column[Time]("start")
def end = column[Time]("end")
def teacher = column[String]("teacher")
def auditorium = column[Int]("auditorium")
override def * = (name, day, subject, typeSub, start, end, teacher, auditorium) <>((Group.apply _).tupled, Group.unapply)
}
Run Code Online (Sandbox Code Playgroud)
application.conf:
slick.dbs.default.driver = "slick.driver.MySQLDriver$"
slick.dbs.default.db.driver="com.mysql.jdbc.Driver"
slick.dbs.default.db.url="jdbc:mysql://localhost:3306/testdb"
slick.dbsdefault.user="root"
slick.dbs.default.password=""
play.evolutions.autoApply=true
evolutionplugin=enabled
play.evolutions.db.default.autoApply=true
play.evolutions.db.default.autoApplyDowns=true
Run Code Online (Sandbox Code Playgroud)
built.sbt:
name := "TimetableAPI"
version := …
Run Code Online (Sandbox Code Playgroud) 我目前正在学习Play2,Scala和Slick 3.1,并且我非常坚持使用insertOrUpdate的语法,并想知道是否有人可以帮助我.
我想要做的是在使用insertOrUpdate(包括auto inc主键)时返回完整行,但我只是设法返回更新/插入的行数.
这是我的表定义:
package models
final case class Report(session_id: Option[Long], session_name: String, tester_name: String, date: String, jira_ref: String,
duration: String, environment: String, notes: Option[String])
trait ReportDBTableDefinitions {
import slick.driver.PostgresDriver.api._
class Reports(tag: Tag) extends Table[Report](tag, "REPORTS") {
def session_id = column[Long]("SESSION_ID", O.PrimaryKey, O.AutoInc)
def session_name = column[String]("SESSION_NAME")
def tester_name = column[String]("TESTER_NAME")
def date = column[String]("DATE")
def jira_ref = column[String]("JIRA_REF")
def duration = column[String]("DURATION")
def environment = column[String]("ENVIRONMENT")
def notes = column[Option[String]]("NOTES")
def * = (session_id.?, session_name, tester_name, date, jira_ref, …
Run Code Online (Sandbox Code Playgroud)我可以使用Slick/Play Framework(Scala)来收听PostgreSQL NOTIFY语句吗?
我想做类似的事情:
http://bjorngylling.com/2011-04-13/postgres-listen-notify-with-node-js.html