Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何在Slick中的一系列数据库查询之间包含scala操作?_Postgresql_Scala_Slick - Fatal编程技术网

Postgresql 如何在Slick中的一系列数据库查询之间包含scala操作?

Postgresql 如何在Slick中的一系列数据库查询之间包含scala操作?,postgresql,scala,slick,Postgresql,Scala,Slick,假设我有一个模型,看起来像这样: case class User(username: String, dateOfBirth: Timestamp, lastSentGift: Timestamp) 假设我有一个合适的Slick模式,Users,如何在一个事务中对该表执行多个查询,并在其间调用scala函数 我已经看到Slick提供了一个DBIOAction和DBIO.seq来允许在一个事务中组合多个数据库操作,但我不知道是否/如何将它们与中间调用的scala函数一起使用 例如,我想做这样的事

假设我有一个模型,看起来像这样:

case class User(username: String, dateOfBirth: Timestamp, lastSentGift: Timestamp)
假设我有一个合适的Slick模式,
Users
,如何在一个事务中对该表执行多个查询,并在其间调用scala函数

我已经看到Slick提供了一个
DBIOAction
DBIO.seq
来允许在一个事务中组合多个数据库操作,但我不知道是否/如何将它们与中间调用的scala函数一起使用

例如,我想做这样的事情,但将所有内容都保存在一个事务中:

def prepareGiftFor(user: User): Timestamp = ???

val usersWithBirthdays = db.run(
  Users.filter { user => 
    user.dateOfBirth > (now - 1 month) && user.lastSentGift < (now - 1 month)
  }
  .limit(100)
  .forUpdate
)

usersWithBirthdays
  .map(user => (user.username, prepareGiftFor(user)))
  .map { case (username, lastSentGift) =>
    db.run(
      Users.withFilter(_.username === username)
        .map(row => row.lastSentGift)
        .update(lastSentGift)
    )
  }
def prepareGiftFor(用户:用户):时间戳=???
val usersWithBirthdays=db.run(
Users.filter{user=>
user.dateOfBirth>(现在-1个月)和&user.lastSentGift<(现在-1个月)
}
.限额(100)
.forUpdate
)
用户生日
.map(user=>(user.username,prepareGiftFor(user)))
.map{case(用户名,lastSentGift)=>
db.run(
Users.withFilter(uz.username==用户名)
.map(行=>row.lastSentGift)
.更新(最新)
)
}

slick的一般想法是延迟
db。尽可能多地运行
调用。首选的方法是使用
DBIOAction
实例,并像使用scala
Future
选项一样链接它们

为此,
DBIOAction
支持
map
flatMap
方法。companion对象还包含来自
成功
失败
的助手方法。使用它们,您可以从基本值构造
DBIOAction
。有关更多信息,请查看“关于合成的操作”的本节

通过调用
DBIOAction
实例,可以在单个事务中运行所有sql请求

您的示例可以改写为:

def prepareGiftFor(user: User): Timestamp = ???

def findUsersWithBirthdays(): DBIO[Seq[User]] = {
  Users
    .filter { user =>
      user.dateOfBirth > (now - 1 month) && user.lastSentGift < (now - 1 month)
    }
    .limit(100)
    .forUpdate
}

def updateUsers(users: Seq[User]): Seq[DBIO[Int]] = {
  users
    .map(user => (user.username, prepareGiftFor(user)))
    .map {
      Users
        .withFilter(_.username === username)
        .map(row => row.lastSentGift)
        .update(lastSentGift)
    }
}

db.run(
  (for {
    users <- findUsersWithBirthdays()
    _ <- DBIO.sequience(updateUsers(users))
  } yield ()).transactionaly
)
def prepareGiftFor(用户:用户):时间戳=???
def findUsersWithBirthdays():DBIO[Seq[User]={
使用者
.filter{user=>
user.dateOfBirth>(现在-1个月)和&user.lastSentGift<(现在-1个月)
}
.限额(100)
.forUpdate
}
def更新用户(用户:Seq[User]):Seq[DBIO[Int]={
使用者
.map(user=>(user.username,prepareGiftFor(user)))
.地图{
使用者
.withFilter(u.username==用户名)
.map(行=>row.lastSentGift)
.更新(最新)
}
}
db.run(
(用于{
使用者