【问题标题】:how to insert usert defined type in cassandra by using lagom scala framework如何使用 lagom scala 框架在 cassandra 中插入用户定义的类型
【发布时间】:2019-11-09 17:35:27
【问题描述】:

我正在使用 Lagom(scala) 框架,我可以找到任何方法来将具有复杂类型的 scala 案例类对象保存在 cassandra 中。那么如何在 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()
  } 

【问题讨论】:

  • @UDT 注释仅用于对象映射器 - 它对“直接”插入没有帮助 - 请参阅我在对上一个问题的评论中添加的链接

标签: scala cassandra lagom


【解决方案1】:

我遇到了同样的问题并通过以下方式解决:

  1. 定义类型和表格:
     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. 像这样在buildHandler()中调用这个方法:
      override def buildHandler(): ReadSideProcessor.ReadSideHandler[FacilityEvent] =
        readSide.builder[PropertiesEvent]("PropertiesOffset")
          .setPrepare(_ => prepare())
          .setGlobalPrepare(() => {
            createTable()
          })
          .setEventHandler[PropertiesCreated](processPropertiesCreated)
          .build()
  1. 然后在 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. 然后这样读:
  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. 我的prepare()函数:
  private def prepare(): Future[Done] = {
    val f = session.prepare("INSERT INTO leadpropertiestable (id, options) VALUES (?, ?)")
    writePromise.completeWith(f)
    f.map(_ => Done)
  }

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

【讨论】:

    猜你喜欢
    • 2018-09-25
    • 2017-09-23
    • 2018-03-08
    • 1970-01-01
    • 2018-07-02
    • 2017-01-07
    • 2018-04-14
    • 1970-01-01
    • 2021-08-25
    相关资源
    最近更新 更多