ファントムの作者としての少し偏った見方ですが、私はファントムの設計目標を非常によく理解しています。Quill ライブラリの Web サイトで利用できる Quill と Phantom の既存の比較がありますが、これは当然逆の方向に偏っています。
Phantom は、アプリケーション レベルのレイヤーに最適な選択肢を目指しています。一方、Quill は最もファンシーな文字列ジェネレーターを目指しているため、Cassandra の上に大規模なアプリを構築する場合、これはあまり有用な比較にはなりません。
ファントムを使うメリット
型安全性と、DSL が Cassandra の機能にどれだけうまく適合しているかに関しては、実際には争いはありません。DSL はデータ構造について非常に「詳細な」知識を持ち、Cassandra 機能を完全にサポートします。コンパイル時に、Cassandra に関して何が可能で何が不可能かを認識します。
Quill の開発者は、phantom にはさらに多くの依存関係があると主張していますが、Play iteratees やストリームのサポートなど、それらのほとんどはオプションであるため、完全に正確ではありません。欲しくないものは手に入れられない、それは簡単なことです。
Quill の比較では、「簡単なプロセスではないかもしれませんが、DSL を拡張して新しい機能を追加することで Phantom を拡張できます」と単純に述べられていますが、これは少し不正確です。ゲームの初心者である Quill は、Cassandra 機能のサポートに関してはおもちゃであり、多くの場合、機能を追加する必要があることに気付くでしょう。Phantom には間違いなくギャップがありますが、はるかに成熟した代替手段であり、拡張が必要になる回数は非常にまれです。
より複雑な機能については、数日または数週間以内にほとんどのバグに対処しましたが、通常、必要な機能はすべて既に存在しており、現在 Quill にはない多くの機能については、書き留めるのに何時間もかかるでしょう.
私は JPA のバックグラウンドが強いわけではありませんが、マッピング DSL からテーブルのスキーマ全体を直接自動生成できるため、Cassandra とファントムの間のマッピングは非常に強力なレイヤーです。また、DSL がコンパイル時に Cassandra の動作を完全に模倣できるようにします。選択した主キーなどに関してどのクエリが可能かを認識しますが、quill ではそのようなサポートはまったくありません。
Phantom には、コネクタ、データベース、データベースの自動生成、アプリケーションを本番環境で実行するのに役立つものなど、非常に強力なアプリケーション レベルの抽象化レイヤーがあります。
Quill の背後にあるコードははるかに複雑であり、その背後にあるエンジニアリング能力を高く評価するのは私が初めてですが、ユーザー フレンドリーさを考えると、ストーリーはそれほどうまくいきません。
クイルは一度にもっと多くのことをしようとします。これは生成用のミニ エンジンであり、scalaquery が数年前に SQL データベースに完全に集中することを決定し、それ以外のサポートを中止する前にやろうとしたことです。これは現代の Slick の前身であり、同様の QDSL 引用方式を使用しています。
クイルは漏れのある抽象化です。彼らはより広い範囲のデータベースをサポートすることを目指しているため、db 固有の特殊性に対するサポートは非常に劣っています。以下に例を示します。
あなたが読んだ比較の非常に基本的な例から:
val getAllByCountry = quote {
(country: String) => query[WeatherStation]
.filter(_.country == country)
}
}
必要なマッピング コードを含めると、ファントムに相当するものよりもおそらく冗長ではなくなります。
select.where(_.country eqs country).fetch()
しかし、それをさらに調べてみましょう。そのような単一の国を取得しようとしている場合はどうなりますか? または、情報を取得しようとしている場合はどうなりますPagingState
か? または、既存のものをフィードしPagingState
て UI 上に表示します。
これは、少なくとも比較では、ユーザーの経験が最終的にどうなるかについての実際のプレビューをユーザーに与えることができないところです。ツールのページにアクセスするたびに、そのカテゴリで最高のツールであると説明するのは自然なことですが、それはファントムの背後にいる私たちもそうしていますが、それがすべてではありません.
より簡潔にするために、さらにいくつかの優れた点を示します。
select.where(_.country eqs country).fetchRecord()
select.where(_.country eqs country).one()
部分選択はどうですか?
select(_.country, _.city).where(_.country eqs country)
Phantom は、Cassandra を使用して実行時に可能なすべてのものを意味的に区別し、何よりも、コンパイル時のトリックとドメインの知識を使用して実行時エラーを防止しようとします。どのようにしてQuillに相当するものを手に入れることができますか?
さらに、Quill は から直接クエリを生成することが完全に可能です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)
}
}
ただし、スキーマに関する知識はまったくありません。国が予備選挙に含まれていない場合はどうなりますか? そのクエリは無効です。phantom ではコンパイルできません。これは最も基本的な例にすぎません。
Phantom はテーブルから直接 CQL を自動生成でき、データベース全体をオンザフライで生成できます。プロ バージョンはテーブルを自動移行し、スキーマの不整合に対処するのに役立ち、非常に高度な UI と監視インターフェイスを提供します。その場でスキーマをアップグレードおよびダウングレードできます。
短所
Phantom は確かに のようなものを拡張するために少し冗長にしましTypeCodec
たが、phantom 2.9.0 の時点で、まったく依存しない Cassandra で型をエンコードするための非常に強力なマクロ メカニズムを導入しましたTypeCodec
!
Phantom は、テーブル DSL の定義に関して最小限のボイラープレートを必要としますが、本質的に、テーブル列の共有ではうまく機能しません。それは可能ですが、最も美しいコードでもなければ、最悪のコードでもありません。
全体
- Quill は非常に才能のある人たちによって書かれた非常に優れたソフトウェアであり、それについては疑いの余地はありません。
- クエリ生成では厳密にファントムよりも優れています。EDSL では削減できない QDSL で削減できる定型文があります。
- これは、アプリケーション レイヤーでは非常に劣ったツールであり、ほとんどの人にとってはさらに不自然です。Slick は概念をある程度普及させましたが、アプリケーション ライフサイクルの一部として必要な最も基本的な機能のいくつかは、QDSL を介して簡単にアドレス指定できないか、少なくともまだ実現していません。
- Phantom ははるかに成熟しており、非常に広く採用されており、創設チームからのより多くのリソースとインプット、長期にわたるロードマップ、およびすべての機能を常に把握するのに役立つ Datastax との重要なパートナーシップを備えています。