gpt4 book ai didi

scala - 尝试按 UUID 过滤时出错 - Slick

转载 作者:行者123 更新时间:2023-12-04 11:18:56 25 4
gpt4 key购买 nike

我正在尝试使用以下内容过滤我的表格:

val applicationId = ...
val application = Applications.filter(_.id === applicationId).first

其中 idapplicationId 是 UUID。

我收到的错误是:

scala.slick.SlickException: UUID does not support a literal representation

我发现我需要使用bind:

// val applicationId is a UUID
val application = Applications.filter(_.id === applicationId.bind).first

但是,这是抛出异常

java.util.NoSuchElementException: Invoker.first

即使我正在使用我知道在表中的 UUID 进行查询

这是 Slick 正在生成的 selectStatement。我不确定为什么它不包含 UUID?

select x2."Id" from "Application" x2 where x2."Id" = ?

最佳答案

我今天一直在努力解决这个问题。我不知道我是否有好的解决方案,但我可以提供一些选择。

修补光滑的驱动程序以允许相等性测试

我正在使用 MySQL,该数据库支持将字节数据作为字符串发送的语法:

mysql> desc user;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| user_uuid | binary(16) | NO | PRI | NULL | |
| email | varchar(254) | NO | UNI | NULL | |
| display_name | varchar(254) | NO | | NULL | |
| password_hash | varchar(254) | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
4 rows in set (0.01 sec)

mysql> select * from user where user_uuid = x'e4d369040f044b6e9561765c356907d3';
+------------------+-----------------+--------------+---------------+
| user_uuid | email | display_name | password_hash |
+------------------+-----------------+--------------+---------------+
| ???????????? | foo@example.com | Foo | NULL |
+------------------+-----------------+--------------+---------------+
1 row in set (0.00 sec)

显示 UUID 是正确的:

mysql> select hex(user_uuid), email, display_name from user where user_uuid = x'e4d369040f044b6e9561765c356907d3';
+----------------------------------+-----------------+--------------+
| hex(user_uuid) | email | display_name |
+----------------------------------+-----------------+--------------+
| E4D369040F044B6E9561765C356907D3 | foo@example.com | Foo |
+----------------------------------+-----------------+--------------+

在此基础上,MySQLDriver.scala(版本 1.0.1)的以下补丁运行良好:

$ git diff
diff --git a/src/main/scala/scala/slick/driver/MySQLDriver.scala b/src/main/scala/scala/slick/driver/
index 84a667e..1aa5cca 100644
--- a/src/main/scala/scala/slick/driver/MySQLDriver.scala
+++ b/src/main/scala/scala/slick/driver/MySQLDriver.scala
@@ -174,9 +174,15 @@ trait MySQLDriver extends ExtendedDriver { driver =>
}
}

+ import java.util.UUID
+
override val uuidTypeMapperDelegate = new UUIDTypeMapperDelegate {
override def sqlType = java.sql.Types.BINARY
override def sqlTypeName = "BINARY(16)"
+
+ override def valueToSQLLiteral(value: UUID): String =
+ "x'"+value.toString.replace("-", "")+"'"
}
}
}

有了它,您可以编写如下代码:

def findUserByUuid(uuid: UUID): Option[UserRecord] = db.withSession {
// Note: for this to work with slick 1.0.1 requires a tweak to MySQLDriver.scala
// If you don't, the "===" in the next line will fail with:
// "UUID does not support a literal representation".
val query = (for (u <- UserRecordTable if u.uuid === uuid) yield u)
query.firstOption
}

我不确定您使用的是哪个数据库,但类似的方法可能会奏效。我还没有对这些进行任何性能测试。

将UUID编码为字节数组

有几个选项可以避免光滑的代码补丁。

使用来自 http://nineofclouds.blogspot.com.au/2013/04/storing-uuids-with-anorm.html 的 UUIDHelper ,您可以将 UUID 编码为字节数组并进行静态查询。有点不雅,但工作方式如下:

import UuidHelper

implicit object SetUUID extends SetParameter[UUID] {
def apply(v: UUID, pp: PositionedParameters) { pp.setBytes(UuidHelper.toByteArray(v)) }
}
implicit val getUserRecordResult = GetResult(r =>
UserRecord(UuidHelper.fromByteArray(r.nextBytes()), r.<<, r.<<, r.<<)
)

val userByUuid = StaticQuery[UUID, UserRecord] + "select * from user where user_uuid = ?"
val user = userByUuid(user.uuid).first
// do what you want with user.

将 UUID 编码为十六进制字符串

以下可能是最不优雅的,但为了完整性而包括在内:

implicit val getUserRecordResult = GetResult(r => UserRecord(UuidHelper.fromByteArray(r.nextBytes()), r.<<, r.<<, r.<<))

val uuid = user.uuid.toString.replace("-", "")
val userByUuid = StaticQuery.queryNA[UserRecord](s"select * from user where user_uuid = x'$uuid'")
val user = userByUuid().first

HTH

编辑:下面是针对 master 的拉取请求。请注意,拉取请求是针对 master (2.0.0) 的,但我仅针对 1.0.1 成功测试了它。

https://github.com/slick/slick/pull/240

关于scala - 尝试按 UUID 过滤时出错 - Slick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17496415/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com