【问题标题】:Scala Slick compose column type mappersScala Slick 撰写列类型映射器
【发布时间】:2017-10-17 08:15:50
【问题描述】:

我正在使用 slick-pg,它为 slick 中的 List 和 DateTime 类型添加了支持(带有隐式)。

不幸的是,我不能使用 List[DateTime] - slick 不了解这些类型的组成,但我已经检查过它们是否都能正常工作(例如 List[Int] 和 DateTime)。

有没有办法轻松组合这两个隐式?

【问题讨论】:

    标签: postgresql scala slick slick-pg


    【解决方案1】:

    1.尝试添加

      implicit def dateTimeList =
        MappedColumnType.base[List[DateTime], List[Timestamp]](
          _.map(dt => new Timestamp(dt.getMillis)),
          _.map(ts => new DateTime(ts.getTime))
        )
    

    以防万一,编译的整个代码:

    import java.sql.Timestamp
    import org.joda.time.DateTime
    import slick.jdbc.PostgresProfile.api._
    import slick.lifted.ProvenShape
    import slick.basic.Capability
    import slick.jdbc.JdbcCapabilities
    import com.github.tototoshi.slick.PostgresJodaSupport._
    import com.github.tminglei.slickpg._
    
    object App {
    
      trait MyPostgresProfile extends ExPostgresProfile
        with PgArraySupport
        with PgDate2Support
        with PgRangeSupport
        with PgHStoreSupport
    //    with PgPlayJsonSupport
        with PgSearchSupport
    //    with PgPostGISSupport
        with PgNetSupport
        with PgLTreeSupport {
        def pgjson = "jsonb" // jsonb support is in postgres 9.4.0 onward; for 9.3.x use "json"
    
        // Add back `capabilities.insertOrUpdate` to enable native `upsert` support; for postgres 9.5+
        override protected def computeCapabilities: Set[Capability] =
          super.computeCapabilities + /*JdbcProfile.capabilities.insertOrUpdate*/ JdbcCapabilities.insertOrUpdate
    
        override val api = MyAPI
    
        object MyAPI extends API with ArrayImplicits
          with DateTimeImplicits
    //      with JsonImplicits
          with NetImplicits
          with LTreeImplicits
          with RangeImplicits
          with HStoreImplicits
          with SearchImplicits
          with SearchAssistants {
          implicit val strListTypeMapper = new SimpleArrayJdbcType[String]("text").to(_.toList)
    //      implicit val playJsonArrayTypeMapper =
    //        new AdvancedArrayJdbcType[JsValue](pgjson,
    //          (s) => utils.SimpleArrayUtils.fromString[JsValue](Json.parse(_))(s).orNull,
    //          (v) => utils.SimpleArrayUtils.mkString[JsValue](_.toString())(v)
    //        ).to(_.toList)
        }
      }
    
      object MyPostgresProfile extends MyPostgresProfile
    
      import MyPostgresProfile.api._
    
       // This can be used instead of slick-joda-mapper library 
    //  implicit def dateTime =
    //    MappedColumnType.base[DateTime, Timestamp](
    //      dt => new Timestamp(dt.getMillis),
    //      ts => new DateTime(ts.getTime)
    //    )
    
      implicit def dateTimeList =
        MappedColumnType.base[List[DateTime], List[Timestamp]](
          _.map(dt => new Timestamp(dt.getMillis)),
          _.map(ts => new DateTime(ts.getTime))
        )
    
      case class Record(id: Int, name: String, friends: List[Int], registered: DateTime, visits: List[DateTime])
    
      class RecordTable(tag: Tag) extends Table[Record](tag, Some("public"), "records") {
        def id: Rep[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc)
        def name: Rep[String] = column[String]("name")
        def friends: Rep[List[Int]] = column[List[Int]]("friends")
        def registered: Rep[DateTime] = column[DateTime]("registered")
        def visits: Rep[List[DateTime]] = column[List[DateTime]]("visits")
        def * : ProvenShape[Record] = (id, name, friends, registered, visits) <> (Record.tupled, Record.unapply)
      }
    
      val records: TableQuery[RecordTable] = TableQuery[RecordTable]
    }
    

    build.sbt

    name := "slickdemo"
    
    version := "0.1"
    
    scalaVersion := "2.12.3"
    
    libraryDependencies += "com.typesafe.slick" %% "slick" % "3.2.1"
    libraryDependencies += "org.slf4j" % "slf4j-nop" % "1.7.25"
    libraryDependencies += "com.typesafe.slick" %% "slick-hikaricp" % "3.2.1"
    
    libraryDependencies += "org.postgresql" % "postgresql" % "42.1.4"
    
    libraryDependencies += "com.github.tminglei" %% "slick-pg" % "0.15.3"
    
    libraryDependencies += "joda-time" % "joda-time" % "2.9.9"
    libraryDependencies += "org.joda" % "joda-convert" % "1.9.2"
    libraryDependencies += "com.github.tototoshi" % "slick-joda-mapper_2.12" % "2.3.0"
    

    基于answer 和documentation。


    2. 或者您可以添加

        implicit val dateTimeArrayTypeMapper =
            new AdvancedArrayJdbcType[DateTime]("timestamp",
              (s) => utils.SimpleArrayUtils.fromString[DateTime](DateTime.parse)(s).orNull,
              (v) => utils.SimpleArrayUtils.mkString[DateTime](_.toString)(v)
            ).to(_.toList)
    

    在strListTypeMapper 和playJsonArrayTypeMapper 之后。

    【讨论】:

    • 我想知道是否可以在不制作自己的映射器的情况下做到这一点,因为我有 List 和 DateTime 的隐式映射器 - 带有一些导入或其他东西。所以我看到不幸的是没有。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多