如何使用lagomscala框架在cassandra中插入usert定义的类型

a8jjtwal  于 2021-06-14  发布在  Cassandra
关注(0)|答案(1)|浏览(432)

我正在使用lagom(scala)框架,我可以找到任何方法来保存cassandra中具有复杂类型的scala case类对象。那么如何在lagom scala中插入cassandra udt。任何人都可以解释如何使用boundstatement.setudtvalue()方法。

I have tried to do by using com.datastax.driver.mapping.annotations.UDT.
but does not work for me. I have also tried com.datastax.driver.core
 Session Interface. but again it does not.

case class LeadProperties(
                           name: String,
                           label: String,
                           description: String,
                           groupName: String,
                           fieldDataType: String,
                           options: Seq[OptionalData]
                         )
object LeadProperties{
  implicit val format: Format[LeadProperties] = Json.format[LeadProperties]
}
@UDT(keyspace = "leadpropertieskeyspace", name="optiontabletype")
case class OptionalData(label: String)
object OptionalData {
  implicit val format: Format[OptionalData] = Json.format[OptionalData]
}

my query:----
val optiontabletype= """
      |CREATE TYPE IF NOT EXISTS optiontabletype(
      |value text
      |);
    """.stripMargin

   val createLeadPropertiesTable: String =       """
                          |CREATE TABLE IF NOT EXISTS leadpropertiestable(
                          |name text Primary Key,
                          |label text,
                          |description text,
                          |groupname text,
                          |fielddatatype text,
                          |options List<frozen<optiontabletype>>
                          );
                        """.stripMargin

def createLeadProperties(obj: LeadProperties): Future[List[BoundStatement]] = {
    val bindCreateLeadProperties: BoundStatement = createLeadProperties.bind()
    bindCreateLeadProperties.setString("name", obj.name)
    bindCreateLeadProperties.setString("label", obj.label)
    bindCreateLeadProperties.setString("description", obj.description)
    bindCreateLeadProperties.setString("groupname", obj.groupName)
    bindCreateLeadProperties.setString("fielddatatype", obj.fieldDataType)

     here is the problem I am not getting any method for cassandra Udt.

    Future.successful(List(bindCreateLeadProperties))
  }

override def buildHandler(): ReadSideProcessor.ReadSideHandler[PropertiesEvent] = {
    readSide.builder[PropertiesEvent]("PropertiesOffset")
      .setGlobalPrepare(() => PropertiesRepository.createTable)
      .setPrepare(_ => PropertiesRepository.prepareStatements)
      .setEventHandler[PropertiesCreated](ese ⇒ 
        PropertiesRepository.createLeadProperties(ese.event.obj))
      .build()
  }
0yg35tkg

0yg35tkg1#

我也面临着同样的问题,并按照以下方式解决:
定义类型和表:

def createTable(): Future[Done] = {
        session.executeCreateTable("CREATE TYPE IF NOT EXISTS optiontabletype(filed1 text, field2 text)")
          .flatMap(_ => session.executeCreateTable(
            "CREATE TABLE IF NOT EXISTS leadpropertiestable ( " +
              "id TEXT, options list<frozen <optiontabletype>>, PRIMARY KEY (id))"
          ))
      }

在buildhandler()中调用此方法,如下所示:

override def buildHandler(): ReadSideProcessor.ReadSideHandler[FacilityEvent] =
        readSide.builder[PropertiesEvent]("PropertiesOffset")
          .setPrepare(_ => prepare())
          .setGlobalPrepare(() => {
            createTable()
          })
          .setEventHandler[PropertiesCreated](processPropertiesCreated)
          .build()

然后在processpropertiescreated()中,我像这样使用它:

private val writePromise = Promise[PreparedStatement] // initialized in prepare
  private def writeF: Future[PreparedStatement] = writePromise.future

  private def processPropertiesCreated(eventElement: EventStreamElement[PropertiesCreated]): Future[List[BoundStatement]] = {
    writeF.map { ps =>
      val userType = ps.getVariables.getType("options").getTypeArguments.get(0).asInstanceOf[UserType]
      val newValue = userType.newValue().setString("filed1", "1").setString("filed2", "2")
      val bindWriteTitle = ps.bind()
      bindWriteTitle.setString("id", eventElement.event.id)
      bindWriteTitle.setList("options", eventElement.event.keys.map(_ => newValue).toList.asJava) // todo need to convert, now only stub
      List(bindWriteTitle)
    }
  }

这样读:

def toFacility(r: Row): LeadPropertiesTable = {
    LeadPropertiesTable(
      id = r.getString(fId),
      options = r.getList("options", classOf[UDTValue]).asScala.map(udt => OptiontableType(field1 = udt.getString("field1"), field2 = udt.getString("field2"))
    )
  }

my prepare()函数:

private def prepare(): Future[Done] = {
    val f = session.prepare("INSERT INTO leadpropertiestable (id, options) VALUES (?, ?)")
    writePromise.completeWith(f)
    f.map(_ => Done)
  }

这不是一个很好写的代码,但我认为将有助于继续工作。

相关问题