Play-Slick中Update与Delete查询无法工作的问题排查
解决Play-Slick CRUD的更新/删除类型不匹配问题
首先,我们来拆解你遇到的核心问题:
type mismatch; found : ... FixedSqlAction[Int,...] required: ... DBIOAction[Seq[models.User],...]
这个错误说明你定义的方法返回值类型(Future[Seq[Person]])和Slick实际操作返回的类型(Future[Int],代表受影响的行数)不匹配。另外还有一个隐藏问题:你的表中id是Long类型,但方法参数用了Int,类型不统一也会引发问题。
下面是具体的修复方案:
1. 修正删除方法(del)
Slick的delete操作返回的是成功删除的记录行数,而不是Seq[Person]。如果你只需要知道删除了多少条记录,修改方法返回类型为Future[Int],同时统一id的类型为Long:
def del(id: Long): Future[Int] = db.run { people.filter(_.id === id).delete }
如果你希望删除后返回剩余的所有用户列表,可以调整逻辑为先删除再查询:
def delAndList(id: Long): Future[Seq[Person]] = { db.run(people.filter(_.id === id).delete).flatMap { _ => list() // 调用已有的list方法返回所有用户 } }
2. 修正更新方法(update)
同样,Slick的update操作默认返回受影响的行数。另外你当前的代码硬编码了更新值为"john",没有使用传入的name参数,这也需要修正。
方案A:返回受影响的行数
def update(id: Long, name: String, age: Int): Future[Int] = db.run { people.filter(_.id === id).map(p => (p.name, p.age)).update((name, age)) }
方案B:返回更新后的用户记录
如果需要确认更新后的结果,可以在更新后查询对应的用户:
def updateAndGet(id: Long, name: String, age: Int): Future[Option[Person]] = { val updateAction = people.filter(_.id === id).map(p => (p.name, p.age)).update((name, age)) db.run(updateAction).flatMap { affectedRows => // 如果有记录被更新,查询该用户;否则返回None if (affectedRows > 0) db.run(people.filter(_.id === id).result.headOption) else Future.successful(None) } }
3. 检查类型一致性
确保你的Person case类的id类型是Long(和表定义一致):
case class Person(id: Long, name: String, age: Int)
额外提示
你的导入语句没有问题,import dbConfig._和import profile.api._已经包含了Slick操作所需的所有隐式转换和API。
内容的提问来源于stack exchange,提问作者Alex Irabor
相关产品推荐
相关产品推荐

