将此代码转换为基于 scala 的循环构造的一种方法如下:
import scala.collection.JavaConversions._
val result = keyspace
.prepareQuery(CQL3_CF)
.withCql("SELECT * FROM employees WHERE empId='111';")
.execute();
result.getResult().getRows() foreach { row =>
LOG.info("CQL Key: " + row.getKey())
val columns = row.getColumns()
LOG.info(" empid : " + columns.getIntegerValue("empid", null))
LOG.info(" deptid : " + columns.getIntegerValue("deptid", null))
LOG.info(" first_name : " + columns.getStringValue ("first_name", null))
LOG.info(" last_name : " + columns.getStringValue ("last_name", null))
}
通过导入 JavaConversions._,我们可以访问一个隐式转换,它将 Java Iterable(即 Rows 对象)转换为 a scala.collection.Iterable
,从而允许您使用foreach
循环构造。
现在,这段代码在语法上是合理的,但它并不是真正好的 Scala 代码。它不是很实用,因为循环本身不返回任何东西。它还有一些处理空值的混乱逻辑,可能应该使用 Options 来代替。一个更实用的解决方案示例,map
用于将结果数据映射到一个简单的案例类,如下所示:
import scala.collection.JavaConversions._
val result = keyspace
.prepareQuery(CQL3_CF)
.withCql("SELECT * FROM employees WHERE empId='111';")
.execute();
case class Employee(id:Option[Int], depId:Option[Int],
firstName:Option[String], lastName:Option[String])
def optFor[T](cl:ColumnList[String], func:(ColumnList[String] => T)):Option[T] = {
func(cl) match{
case null => None
case nonnull => Some(nonnull)
}
}
val employees = result.getResult().getRows() map { row =>
LOG.info("CQL Key: " + row.getKey())
val cl = row.getColumns()
val employee = Employee(optFor(cl, _.getIntegerValue("empid", null)),
optFor(cl, _.getIntegerValue("deptid", null)),
optFor(cl, _.getStringValue("first_name", null)),
optFor(cl, _.getStringValue("last_name", null)))
LOG.info(employee)
employee
}
可能有一种更优雅的方式来处理 null 到Option
转换(也许通过隐式),但这也有效。完成map
操作后,您将拥有一个scala.collection.Iterable
实例Employee
,然后您可能会返回到 UI 进行显示。