如何将java.util.UUID转换为doobie.syntax.SqlInterpolator.SingleFragment?

问题描述

我正在尝试使用doobie,http4s和circe用数据库设置一个简单的scala应用。

如何将java.util.UUID转换为doobie.syntax.SqlInterpolator.SingleFragment?

final case class User(id: UUID,details: UserDetails)
  implicit val userDecoder: Decoder[User] = deriveDecoder[User]
  implicit def userEntityDecoder[F[_]: Sync]: EntityDecoder[F,User] = jsonOf

  implicit val userEncoder: Encoder[User] = deriveEncoder[User]
  implicit def userEntityEncoder[F[_]: Applicative]: EntityEncoder[F,User] = jsonEncoderOf

  implicit val put: Put[User] =
    Put[Json].contramap(_.asJson)

  implicit val get: Get[User] =
    Get[Json].temap(_.as[User].left.map(_.show))

[info] welcome to sbt 1.3.12 (N/A Java 14.0.1)
[info] loading global plugins from /Users/ryan/.sbt/1.0/plugins
[info] loading settings for project bobbymoore-build from plugins.sbt ...
[info] loading project definition from /Users/ryan/fullStackRyan/bobbymoore/project
[info] loading settings for project root from build.sbt ...
[info] set current project to bobbymoore (in build file:/Users/ryan/fullStackRyan/bobbymoore/)
[info] sbt server started at local:///Users/ryan/.sbt/1.0/server/90f560b1e0964865fc4c/sock
sbt:bobbymoore> compile
[info] Compiling 1 Scala source to /Users/ryan/fullStackRyan/bobbymoore/target/scala-2.13/classes ...
[error] /Users/ryan/fullStackRyan/bobbymoore/src/main/scala/com/c/bobbymoore/database/UserQueries.scala:24:20: type mismatch;
[error]  found   : java.util.UUID
[error]  required: doobie.syntax.SqlInterpolator.SingleFragment
[error]          |  ${user.id},[error]                    ^
[error] /Users/ryan/fullStackRyan/bobbymoore/src/main/scala/com/c/bobbymoore/database/UserQueries.scala:34:21: type mismatch;
[error]  found   : java.util.UUID
[error]  required: doobie.syntax.SqlInterpolator.SingleFragment
[error]          |WHERE id=$id
[error]                     ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 2 s,completed 13 Oct 2020,16:31:46

解决方法

如果您使用的是PostgreSQL,而Java中的UUID转换为Postgres表中的UUID列,则必须使用Postgres extensions for Doobie

// other doobie imports
import doobie.postgres._
import doobie.postgres.implicits._

sql"""SELECT id,name FROM users WHERE id = ${user.id}""".query[(UUID,String)]

如果您不使用PSQL并且此UUID映射到TEXT字段,则您必须自己在查询中映射它:

sql"""SELECT id,name FROM users WHERE id = ${user.id.toString}"""
  .query[(String,String)]
  .map { case (uuid,name) => (UUID.fromString(uuid),name) }

或定义自己的Meta[UUID]实例,例如

implicit val uuidMeta: Meta[UUID] =
  Meta[String].imap[UUID](UUID.fromString)(_.toString)

如果要派生实例,例如包含UUID的案例类。 Postgres扩展库提供了一个与PSQL实现匹配的库。

如果您使用例如,您肯定必须定义自己的元实例。 Array[Byte]或数据库端的其他一些数字表示形式来表示UUID。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...