Phantom vs Quill for Playframework(Scala)和Cassandra

Moj*_*ojo 3 cassandra phantom-dsl playframework-2.5

我目前正在考虑使用Cassandra作为PlayFramework项目中的数据库.我正在寻找一个反应性的驱动程序,似乎我的选择仅限于Phantom和Quill.我对nosql数据库的经验仅限于MongoDB,之前我没有使用任何Quill或Phantom.

看看这里比较,似乎最终可能会在Phantom中编写更多代码.此外,使用DSL来描述模型似乎是违反直觉的(来自沉重的休眠/ JPA背景) - 但这可能只是我.

我想知道是否有人可以提供实用的建议/用例,其中一个人会优于另一个人以及每个人需要注意的事项?

fla*_*ian 9

作为幻影作者的一个略微偏见的观点,我非常了解幻影中的设计目标.Quill图书馆网站上现有的Quill和Phantom之间存在比较,这在另一个方向上自然存在偏差.

Phantom旨在成为应用程序级别层的完美选择,其中Quill旨在成为最狂热的字符串生成器,当您在Cassandra上构建大型应用程序时,这不是一个非常有用的比较.

使用幻像的优点

  • 关于类型安全以及DSL对Cassandra功能的改进程度,确实没有竞争.DSL对您的数据结构有非常"亲密"的了解,并为Cassandra功能提供全面支持.它在编译时知道Cassandra有什么可能,有什么不可能.

  • Quill devs认为幻影有很多依赖关系,但这并不完全准确,因为大多数都是可选的,包括Play iteratees和stream支持等.你不希望你得到什么,这很简单.

  • Quill比较简单地说:"你可以通过扩展DSL扩展Phantom以添加新功能,虽然它可能不是一个简单的过程.",这有点不准确.作为游戏中的新玩家,Quill在Cassandra功能支持方面是一个玩具,你经常会发现自己需要添加功能.Phantom毫无疑问有它的缺口,但它是一个远远更成熟的替代品,并且需要扩展的次数非常少.

  • 我们已经针对更复杂的功能在几天或几周内解决了大多数错误,但通常您可能需要的所有内容都已经存在,目前Quill中找不到许多功能,甚至需要几个小时才能写下来.

  • 我不是来自强大的JPA背景,但Cassandra和幻像之间的映射是一个非常强大的层,因为它允许您直接从映射DSL自动生成表的整个模式.它还允许DSL在编译时完全模仿Cassandra的行为,它将知道哪些查询可能与您选择的主键有关等等,quill根本没有这样的支持.

  • Phantom拥有非常强大的应用程序级抽象层,例如连接器,数据库,数据库的自动生成,以及帮助您将应用程序运行到生产中的东西.

  • Quill背后的代码要复杂得多,虽然我是第一个对其背后的工程能力给予强烈信任的人,但当我认为用户友好时,这个故事并没有得到很好的支持.

  • Quill试图一次性完成更多工作.它是一代的迷你引擎,在他们决定完全专注于SQL dbs并放弃对其他任何东西的支持之前,scalaquery试图做几年之前做的事情.它是现代Slick的前身,并使用类似的QDSL引用方法.

  • Quill是一个泄漏的抽象.由于他们的目标是支持更广泛的数据库,因此他们对数据库特性的特殊性的支持非常低劣.一个例子如下:

从比较中的基本示例中可以看出:

val getAllByCountry = quote {
  (country: String) => query[WeatherStation]
     .filter(_.country == country)
  }
}
Run Code Online (Sandbox Code Playgroud)

如果我们包含必要的映射代码,那么到目前为止所有这些都可能比幻像等价物更简洁.

select.where(_.country eqs country).fetch()
Run Code Online (Sandbox Code Playgroud)

但让我们进一步探索.如果你试图像这样取一个国家怎么办?或者如果你想获取PagingState信息怎么办?或者提供现有内容PagingState以通过UI显示内容.

这是Quill至少在比较中无法向用户提供他们的体验最终结果的真实预览的地方.很自然地假设,无论何时进入工具页面,它都会将自己描述为同类产品中的最佳工具,因为我们肯定会在幻影背后做到这一点,但这绝不是完整的故事.

为了更简洁,还有一些更酷的东西:

select.where(_.country eqs country).fetchRecord()
select.where(_.country eqs country).one()
Run Code Online (Sandbox Code Playgroud)

部分选择怎么样?

select(_.country, _.city).where(_.country eqs country)
Run Code Online (Sandbox Code Playgroud)

Phantom在语义上区分使用Cassandra在运行时可能发生的所有事情,并且它首先尝试使用编译时技巧和域知识来防止运行时错误.你怎么能相同的羽毛笔?

此外,Quill完全能够直接从a生成查询case class.

  case class WeatherStation(
    country: String,
    city: String,
    stationId: String,
    entry: Int,
    value: Int
  )

  object WeatherStation {

    val getAllByCountry = quote {
      (country: String) =>
        query[WeatherStation].filter(_.country == country)
    }

    val getAllByCountryAndCity = quote {
      (country: String, city: String) =>
        getAllByCountry(country).filter(_.city == city)
    }

    val getAllByCountryCityAndId = quote {
      (country: String, city: String, stationId: String) =>
        getAllByCountryAndCity(country, city).filter(_.stationId == stationId)
    }
  }
Run Code Online (Sandbox Code Playgroud)

但它缺乏任何关于您的架构的知识.如果国家不是小学的一部分怎么办?该查询无效,幻像不会让你编译它,这只是最基本的例子.

Phantom可以直接从表中自动生成您的CQL,它可以动态生成整个数据库,专业版甚至可以自动迁移表并帮助您处理模式不一致,并为您提供非常高级的UI和监控界面可以动态升级和降级模式.

缺点

  • Phantom确实使得扩展类似的东西略显冗长TypeCodec,但是从幻像2.9.0开始,我们引入了一个非常强大的宏机制来编码Cassandra中完全不依赖的类型TypeCodec!

  • Phantom在定义表DSL方面需要最少的样板,并且本质上与共享表列无关.它可以做到,但它不是最漂亮的代码,也不是最糟糕的代码.

总体

  • Quill是一个非常好的软件,由非常有才华的人写的,对此有0个疑问.
  • 在查询生成时,它比幻像更好,可以通过QDSL减少无法通过EDSL减少的样板,如果我们正在争夺哪个是最卑鄙最卑鄙的字符串生成器Quill胜利.
    • 它在应用层是一个非常低劣的工具,对大多数人来说更加不自然.Slick在某种程度上推广了这些概念,但是作为应用程序生命周期的一部分,您想要的一些最基本的功能并不像QDSL那样容易解决,或者至少它还没有发生.
    • Phantom更成熟,更广泛采用,拥有更多资源和创始团队的投入,长期的路线图以及与Datastax的重要合作伙伴关系,帮助我们掌握所有功能.