简体   繁体   English

如何使用lagom scala框架在cassandra中插入用户定义的类型

[英]how to insert usert defined type in cassandra by using lagom scala framework

I am using Lagom(scala) framework and i could find any way to save scala case class object in cassandra with has complex Type.我正在使用 Lagom(scala) 框架,我可以找到任何方法来在 cassandra 中保存具有复杂类型的 scala case 类对象。 so how to i insert cassandra UDT in Lagom scala.那么如何在 Lagom scala 中插入 cassandra UDT。 and can any one explain hoe to use BoundStatement.setUDTValue() method.任何人都可以解释一下如何使用 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()
  } 

I was faced with the same issue and solve it following way:我遇到了同样的问题并通过以下方式解决它:

  1. Define type and table:定义类型和表:
     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))"
          ))
      }
  1. Call this method in buildHandler() like this:buildHandler() 中调用此方法,如下所示:
      override def buildHandler(): ReadSideProcessor.ReadSideHandler[FacilityEvent] =
        readSide.builder[PropertiesEvent]("PropertiesOffset")
          .setPrepare(_ => prepare())
          .setGlobalPrepare(() => {
            createTable()
          })
          .setEventHandler[PropertiesCreated](processPropertiesCreated)
          .build()
  1. Then in processPropertiesCreated() I used it like:然后在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)
    }
  }
  1. And read it like this:并像这样阅读:
  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"))
    )
  }
  1. My prepare() function:我的prepare()函数:
  private def prepare(): Future[Done] = {
    val f = session.prepare("INSERT INTO leadpropertiestable (id, options) VALUES (?, ?)")
    writePromise.completeWith(f)
    f.map(_ => Done)
  }

This is not a very well written code, but I think will help to proceed work.这不是一个写得很好的代码,但我认为将有助于继续工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM