设为首页 加入收藏

TOP

细谈Slick(6)- Projection:ProvenShape,强类型的Query结果类型(二)
2017-10-10 12:10:48 】 浏览:1682
Tags:细谈 Slick Projection ProvenShape 类型 Query 结果
nt, Option[Double])) * - Unpacked: (Int, (Int, String), (Int, Option[Double])) * - Packed: (Column[Int], Column[(Int, String)], (Column[Int], Column[Option[Double]])) * - Linearized: (Int, Int, String, Int, Option[Double])
*/ abstract class Shape[Level <: ShapeLevel, -Mixed, Unpacked_, Packed_] {...}

上面的Mixed就是ProvenShape的T,Unpacked就是U。如此看来T代表Query[T]的T,而U就是返回结果类型了。如果我们能提供T的Shape隐式实例就能把U升格成ProvenShape[U]。我们来看看Slick官方文件上的例子:

 import scala.reflect.ClassTag // A custom record class
  case class Pair[A, B](a: A, b: B) // A Shape implementation for Pair
  final class PairShape[Level <: ShapeLevel, M <: Pair[_,_], U <: Pair[_,_] : ClassTag, P <: Pair[_,_]]( val shapes: Seq[Shape[_, _, _, _]]) extends MappedScalaProductShape[Level, Pair[_,_], M, U, P] { def buildValue(elems: IndexedSeq[Any]) = Pair(elems(0), elems(1)) def copy(shapes: Seq[Shape[_ <: ShapeLevel, _, _, _]]) = new PairShape(shapes) } implicit def pairShape[Level <: ShapeLevel, M1, M2, U1, U2, P1, P2]( implicit s1: Shape[_ <: Level, M1, U1, P1], s2: Shape[_ <: Level, M2, U2, P2] ) = new PairShape[Level, Pair[M1, M2], Pair[U1, U2], Pair[P1, P2]](Seq(s1, s2)) // Use it in a table definition
  class A(tag: Tag) extends Table[Pair[Int, String]](tag, "shape_a") { def id = column[Int]("id", O.PrimaryKey) def s = column[String]("s") def * = Pair(id, s) } val as = TableQuery[A]

现在Projection可以写成Pair(id,s)。也就是说因为有了implicit def pairShape[...](...):PairShape所以Pair(id,s)被升格成ProvenShape[Pair]。这样Query的返回类型就是Seq[Pair]了。实际上Slick本身提供了Tuple、Case Class、HList等类型的默认Shape隐式实例,所以我们可以把Projection直接写成 def * = (...) 或 Person(...) 或 Int::String::HNil。下面是Tuple的默认Shape:

trait TupleShapeImplicits { @inline implicit final def tuple1Shape[Level <: ShapeLevel, M1, U1, P1](implicit u1: Shape[_ <: Level, M1, U1, P1]): Shape[Level, Tuple1[M1], Tuple1[U1], Tuple1[P1]] =
    new TupleShape[Level, Tuple1[M1], Tuple1[U1], Tuple1[P1]](u1) @inline implicit final def tuple2Shape[Level <: ShapeLevel, M1,M2, U1,U2, P1,P2](implicit u1: Shape[_ <: Level, M1, U1, P1], u2: Shape[_ <: Level, M2, U2, P2]): Shape[Level, (M1,M2), (U1,U2), (P1,P2)] =
    new TupleShape[Level, (M1,M2), (U1,U2), (P1,P2)](u1,u2) ...

回到主题,下面是一个典型的Slick数据库表读取例子:

 1   class TupleTypedPerson(tag: Tag) extends Table[(  2      Option[Int],String,Int,Option[String])](tag,"PERSON") {  3     def id = column[Int]("id",O.PrimaryKey,O.AutoInc)  4     def name = column[String]("name")  5     def age = column[Int]("age")  6     def alias = column[Option[String]]("alias")  7     def * = (id.?,name,age,alias)  8  }  9   val tupleTypedPerson = TableQuery[TupleTypedPerson] 10 
11   val db = Database.forURL("jdbc:h2:mem:test1;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver") 12   val createSchemaAction = tupleTypedPerson.schema.create 13  Await.ready(db.run(createSchemaAction),Duration.Inf) 14   val initDataAction = DBIO.seq { 15     tupleTypedPerson ++= Seq( 16       (Some(0),"Tiger Chan", 45, Some("Tiger_XC")), 17       (Some(0),"Johnny Cox", 17, None), 18       (Some(0),"Cathy Williams", 18, Some("Catty")), 19       (Some(0),"David Wong", 43, None) 20  ) 21  } 22  Await.ready(db.run(initDataAction),Duration.Inf) 23   val queryAction = tupleTypedPerson.result 24 
25   Await.result(db.run(queryAction),Duration.
首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇play for scala 实现SessionFilte.. 下一篇函数式中的 currying

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目