首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ScalaQuery插入BLOB字段?

如何使用ScalaQuery插入BLOB字段?
EN

Stack Overflow用户
提问于 2010-10-22 10:18:12
回答 2查看 4K关注 0票数 6

我使用了ScalaQuery和Scala。

如果我有一个ArrayByte对象,我如何将它插入到表中?

代码语言:javascript
复制
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)

我可以定义使用def extInfo = column[Array[Byte]]("mbody", O.Nullable)的方法吗?如何对BLOB类型字段进行操作(更新、插入、选择)?

顺便说一句:没有ScalaQuery标签

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-22 22:27:40

由于BLOB字段可以为空,因此我建议将其Scala类型更改为OptionBlob,以实现以下定义:

代码语言:javascript
复制
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])

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

代码语言:javascript
复制
      def * = id ~ extInfo.orElse(null) <> (Test, Test.unapply _)

现在来看实际的BLOB处理。读取很简单:您只需在结果中获得一个Blob对象,该对象由JDBC驱动程序实现,例如:

代码语言:javascript
复制
  Query(TestTable) foreach { t =>
    println("mid=" + t.id + ", mbody = " +
      Option(t.extInfo).map { b => b.getBytes(1, b.length.toInt).mkString })
  }

如果要插入或更新数据,则需要创建自己的BLOBs。JDBC的RowSet特性为独立的Blob对象提供了一个合适的实现:

代码语言:javascript
复制
import javax.sql.rowset.serial.SerialBlob

TestTable insert Test(1, null)
TestTable insert Test(2, new SerialBlob(Array[Byte](1,2,3)))

编辑:这里有一个Postgres的TypeMapper[ArrayByte] (ScalaQuery还不支持它的BLOBs ):

代码语言:javascript
复制
  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")
  }
票数 11
EN

Stack Overflow用户

发布于 2011-11-24 04:21:05

我刚刚发布了Scala和SQ的更新代码,也许它会为某些人节省一些时间:

代码语言:javascript
复制
object PostgresByteArrayTypeMapper extends
    BaseTypeMapper[Array[Byte]] with TypeMapperDelegate[Array[Byte]] {
  def apply(p: org.scalaquery.ql.basic.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.nextBytes()
  }
  def updateValue(v: Array[Byte], r: PositionedResult) {
    r.updateBytes(v)
  }
  override def valueToSQLLiteral(value: Array[Byte]) =
    throw new org.scalaquery.SQueryException("Cannot convert BYTEA to literal")

}

然后是用法,例如:

代码语言:javascript
复制
...
// defining a column
def content = column[Array[Byte]]("page_Content")(PostgresByteArrayTypeMapper)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3993434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档