jOOQ将自定义SQL提取到映射器中

时间:2013-12-20 12:14:02

标签: scala jooq mapper

我使用jOOQ来解决一个问题。我可以将动态列添加到mapper/table吗?

SQL

CREATE TABLE "PartnerCategory"
    (
      "ID" uuid NOT NULL,
      "Name" character varying(200),
      "Description" character varying,
      "ParentId" uuid,
      "Visible" boolean,
      CONSTRAINT "PartnerCategory_PK" PRIMARY KEY ("ID")
    )
    WITH (
      OIDS=FALSE
    );
    ALTER TABLE "PartnerCategory"
      OWNER TO postgres;

val SQL_CTE =
    """
      WITH recursive cte1 as (
      select pc."ID", pc."Name", pc."Description", pc."ParentId", pc."Visible", CAST(pc."Name" as text) as Path
        from "PartnerCategory" pc where pc."ParentId" IS NULL
        union
      select pc."ID", pc."Name", pc."Description", pc."ParentId", pc."Visible", ct.Path || ' | ' || CAST(pc."Name" as text) as Path
        from "PartnerCategory" pc
        join cte1 ct on pc."ParentId" = ct."ID"  )
    select ct."ID", ct."Name", ct."Description", ct."ParentId", ct."Visible", ct.Path from cte1 ct
    """.stripMargin

代码

在上面的查询中,我们列出了PartnerCategory中的所有列和一个动态Path的列。 以前要把这一切都搞定,我已经对结果进行了manaully迭代:

val x: Seq[PartnerCategory] = for (i <- abcd.asScala)
    yield PartnerCategory(
        UUID.fromString(i.getValue(0).toString),
        i.getValue(1).toString,
        i.getValue(2).toString,
        i.getValue(3) match {
          case null => None
          case f: UUID => Some(UUID.fromString(f.toString))
        },
        false,
        i.getValue(5).toString)

我有这个表的自定义映射器:

class PartnerCategoryMapper extends RecordMapper[PartnercategoryRecord, PartnerCategory] {
  def map(r: PartnercategoryRecord): PartnerCategory = {
    val pc = PartnerCategory(r.getId, r.getName, r.getDescription, Some(r.getParentid), r.getVisible, "")
    pc.IsNew = false
    pc
  }
}

我的模型看起来像:

case class PartnerCategory(var ID: UUID,var Name: String, var Description: String, var ParentId: Option[UUID], var Visible: Boolean, Path: String)

我试着编写更好的代码,我发现这几乎是完美的。我只是忽略了有关动态列Path的信息:

val F = model.jooq.tables.Partnercategory.PARTNERCATEGORY
val mapper = new PartnerCategoryMapper()
val record = new PartnercategoryRecord()
ctx.fetch(SQL_CTE).into(F).map(mapper).asScala

问题

如何使用1个额外的列获取另一个映射器,例如:

class PartnerCategoryMapperDynamic extends RecordMapper[PartnercategoryRecordWithPath, PartnerCategory] {
  def map(r: PartnercategoryRecordWithPath): PartnerCategory = {
    val pc = PartnerCategory(r.getId, r.getName, r.getDescription, Some(r.getParentid), r.getVisible, r.getPath)
    pc.IsNew = false
    pc
  }
}

1 个答案:

答案 0 :(得分:2)

如果你愿意放弃一些类型安全,你可以写:

class PartnerCategoryMapperDynamic 
extends RecordMapper[Record, PartnerCategory] {
  def map(r: Record): PartnerCategory = {
    val pc = PartnerCategory(
      r.getValue(PARTNER_CATEGORY.ID), 
      r.getValue(PARTNER_CATEGORY.NAME), 
      r.getValue(PARTNER_CATEGORY.DESCRIPTION), 
      Some(r.getValue(PARTNER_CATEGORY.PARENTID)), 
      r.getValue(PARTNER_CATEGORY.VISIBLE),
      if (r.field(PARTNER_CATEGORY_WITH_PATH.PATH) != null)
        r.getValue(PARTNER_CATEGORY_WITH_PATH.PATH)
      else
        ""
    )
    pc.IsNew = false
    pc
  }
}