在ScalaQuery O / R框架中映射自定义类型

时间:2012-06-21 10:19:49

标签: postgresql scala orm scalaquery

在他的comparison of ScalaQuery and Squeryl中,Stefan Zeiger(ScalaQuery的作者)在第三个要点中说:

  

ScalaQuery支持一组基本的JDBC类型,可以   使用DBMS或特定于应用程序的类型进行扩展。

但是,我无法找到如何实际执行此操作的示例或说明。我正在尝试为Postgres数据库编写ScalaQuery模式,其中一些列是我在Postgres中创建的自定义枚举类型。

例如,我有一个名为gender的枚举类型,其值可能为malefemale。这不是Java枚举,作为整数持久保存到数据库。相反,它是DBMS中定义的自定义Postgres类型。 Postgres存储具有特殊4字节数据结构而非原始数据的那些。

如何将gender类型的Postgres列合并到ScalaQuery架构中?

(如果您认为不同的强类型O / R方法更适合该任务,我也会感谢评论。我已经看过Squeryl,并且不相信它可以处理自定义类型,除非它们被持久化作为DBMS中的原语。)

1 个答案:

答案 0 :(得分:3)

import org.scalaquery.ql.{MappedTypeMapper => Mapper}

object TypeMapper {

  type Stamp = java.sql.Timestamp

  val joda2Stamp = 
    Mapper.base[JodaTime, Stamp](
      dt => new Stamp(dt.getMillis), 
      ts => new JodaTime(ts.getTime) )
}

然后,例如,在DAO中(或运行查询的任何地方),使用它:

import TypeMapper._
implicit val j2Stamp = joda2Stamp // type conversion automatically

您需要尝试为Enums和PostGres的枚举存储类型实现相同的功能。我倾向于不打扰,更喜欢使用Java Enums并存储为原始类型。

例如:

public enum CardType implements ILabel {
  V("Visa"),
  M("MasterCard"),
  D("Discover"),
  A("American Express");

  private CardType(String label) { this.label = label; }
  public String getLabel() { return this.label; }
  final String label;

  public static List<String> asList() {
    return EnumHelper.asList(CardType.class);
  }

  public static Map<String,String> asMap() {
    return EnumHelper.asMap(CardType.class);
  }
}

然后在DB a la Orders.insert(cardType = cardType.toString)中存储为char(1),或者您可以创建一个类型映射器Enum-String转换并在插入时省略enum.toString ...