设为首页 加入收藏

TOP

细谈Slick(6)- Projection:ProvenShape,强类型的Query结果类型(一)
2017-10-10 12:10:48 】 浏览:1675
Tags:细谈 Slick Projection ProvenShape 类型 Query 结果

  在Slick官方文档中描述:连接后台数据库后,需要通过定义Projection,即def * 来进行具体库表列column的选择和排序。通过Projection我们可以选择库表中部分列、也可以增加一些自定义列computed column。具体来说Projection提供了数据库表列与Scala值的对应。例如def * = (column1,column2)把库表的column1和column2与(Int,String)对应,column1[Int],column2[String]。也可以说是与定义column的类参数进行对应。从Slick源代码中我们可以找到Projection定义:

abstract class AbstractTable[T](val tableTag: Tag, val schemaName: Option[String], val tableName: String) extends Rep[T] { /** The client-side type of the table as defined by its * projection */ type TableElementType ... /** The * projection of the table used as default for queries and inserts. * Should include all columns as a tuple, HList or custom shape and optionally * map them to a custom entity type using the <> operator. * The `ProvenShape` return type ensures that * there is a `Shape` available for translating between the `Column`-based * type in * and the client-side type without `Column` in the table's type * parameter. */ def * : ProvenShape[T] ... }

我们看到Projection是个ProvenShape[T]类。再看看ProvenShape是怎么定义的:

/** A limited version of ShapedValue which can be constructed for every type * that has a valid shape. We use it to enforce that a table's * projection * has a valid shape. A ProvenShape has itself a Shape so it can be used in * place of the value that it wraps for purposes of packing and unpacking. */ trait ProvenShape[U] { def value: Any val shape: Shape[_ <: FlatShapeLevel, _, U, _] def packedValue[R](implicit ev: Shape[_ <: FlatShapeLevel, _, U, R]): ShapedValue[R, U] def toNode = packedValue(shape).toNode } object ProvenShape { /** Convert an appropriately shaped value to a ProvenShape */
  implicit def proveShapeOf[T, U](v: T)(implicit sh: Shape[_ <: FlatShapeLevel, T, U, _]): ProvenShape[U] =
    new ProvenShape[U] { def value = v val shape: Shape[_ <: FlatShapeLevel, _, U, _] = sh.asInstanceOf[Shape[FlatShapeLevel, _, U, _]] def packedValue[R](implicit ev: Shape[_ <: FlatShapeLevel, _, U, R]): ShapedValue[R, U] = ShapedValue(sh.pack(value).asInstanceOf[R], sh.packedShape.asInstanceOf[Shape[FlatShapeLevel, R, U, _]]) } /** The Shape for a ProvenShape */
  implicit def provenShapeShape[T, P](implicit shape: Shape[_ <: FlatShapeLevel, T, T, P]): Shape[FlatShapeLevel, ProvenShape[T], T, P] = new Shape[FlatShapeLevel, ProvenShape[T], T, P] { def pack(value: Mixed): Packed = value.shape.pack(value.value.asInstanceOf[value.shape.Mixed]).asInstanceOf[Packed] def packedShape: Shape[FlatShapeLevel, Packed, Unpacked, Packed] = shape.packedShape.asInstanceOf[Shape[FlatShapeLevel, Packed, Unpacked, Packed]] def buildParams(extract: Any => Unpacked): Packed = shape.buildParams(extract.asInstanceOf[Any => shape.Unpacked]) def encodeRef(value: Mixed, path: Node) = value.shape.encodeRef(value.value.asInstanceOf[value.shape.Mixed], path) def toNode(value: Mixed): Node = value.shape.toNode(value.value.asInstanceOf[value.shape.Mixed]) } }

从implicit def proveShapeOf[T,U](v:T):ProvenShape[U]可以得出对于任何T,如果能提供Shape[_,_,T,U,_]的隐式实例implicit instance的话就能构建出ProvenShape[U]。我们再看看什么是Shape: 

/** A type class that encodes the unpacking `Mixed => Unpacked` of a * `Query[Mixed]` to its result element type `Unpacked` and the packing to a * fully packed type `Packed`, i.e. a type where everything which is not a * transparent container is wrapped in a `Column[_]`. * * =Example:= * - Mixed: (Column[Int], Column[(Int, String)], (I
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇play for scala 实现SessionFilte.. 下一篇函数式中的 currying

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目