如何使用ScalaQuery插入BLOB字段?

Goo*_*han 6 sql scala scalaquery

我使用了ScalaQuery和Scala.

如果我有一个Array [Byte]对象,我该如何将它插入表中?

object TestTable extends BasicTable[Test]("test") {
  def id = column[Long]("mid", O.NotNull)
  def extInfo = column[Blob]("mbody", O.Nullable)

  def * = id ~ extInfo <> (Test, Test.unapply _)
}

case class Test(id: Long, extInfo: Blob)
Run Code Online (Sandbox Code Playgroud)

我可以使用def extInfo = column[Array[Byte]]("mbody", O.Nullable)BLOB类型字段定义使用的方法,如何操作(UPDATE,INSERT,SELECT)?

BTW:没有ScalaQuery标签

sze*_*ger 11

由于BLOB字段可以为空,我建议将其Scala类型更改为Option [Blob],用于以下定义:

object TestTable extends Table[Test]("test") {
  def id = column[Long]("mid")
  def extInfo = column[Option[Blob]]("mbody")
  def * = id ~ extInfo <> (Test, Test.unapply _)
}

case class Test(id: Long, extInfo: Option[Blob])
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以使用原始的,可以为空的Blob值,但是您需要在列上使用orElse(null)来实际获取空值(而不是抛出异常):

      def * = id ~ extInfo.orElse(null) <> (Test, Test.unapply _)
Run Code Online (Sandbox Code Playgroud)

现在进行实际的BLOB处理.阅读是直截了当的:您只需在结果中获得一个由JDBC驱动程序实现的Blob对象,例如:

  Query(TestTable) foreach { t =>
    println("mid=" + t.id + ", mbody = " +
      Option(t.extInfo).map { b => b.getBytes(1, b.length.toInt).mkString })
  }
Run Code Online (Sandbox Code Playgroud)

如果要插入或更新数据,则需要创建自己的BLOB.JDBC的RowSet功能提供了适用于独立Blob对象的实现:

import javax.sql.rowset.serial.SerialBlob

TestTable insert Test(1, null)
TestTable insert Test(2, new SerialBlob(Array[Byte](1,2,3)))
Run Code Online (Sandbox Code Playgroud)

编辑:这是Postgres的一个TypeMapper [Array [Byte]](ScalaQuery尚不支持BLOB):

  implicit object PostgresByteArrayTypeMapper extends
      BaseTypeMapper[Array[Byte]] with TypeMapperDelegate[Array[Byte]] {
    def apply(p: BasicProfile) = this
    val zero = new Array[Byte](0)
    val sqlType = java.sql.Types.BLOB
    override val sqlTypeName = "BYTEA"
    def setValue(v: Array[Byte], p: PositionedParameters) {
      p.pos += 1
      p.ps.setBytes(p.pos, v)
    }
    def setOption(v: Option[Array[Byte]], p: PositionedParameters) {
      p.pos += 1
      if(v eq None) p.ps.setBytes(p.pos, null) else p.ps.setBytes(p.pos, v.get)
    }
    def nextValue(r: PositionedResult) = {
      r.pos += 1
      r.rs.getBytes(r.pos)
    }
    def updateValue(v: Array[Byte], r: PositionedResult) {
      r.pos += 1
      r.rs.updateBytes(r.pos, v)
    }
    override def valueToSQLLiteral(value: Array[Byte]) =
      throw new SQueryException("Cannot convert BYTEA to literal")
  }
Run Code Online (Sandbox Code Playgroud)