Scala 用の SQL DSL を作成するのに苦労しています。DSL は、Java の一般的なクエリ抽象化レイヤーであるQuerydslの拡張です。
私は今、次のような本当に単純な表現に苦労しています
user.firstName == "Bob" || user.firstName == "Ann"
Querydsl はここで使用できる式モデルを既にサポートしているため、Proxy オブジェクトから Querydsl 式への変換を提供することにしました。プロキシを使用するために、このようなインスタンスを作成します
import com.mysema.query.alias.Alias._
var user = alias(classOf[User])
次の暗黙的な変換により、プロキシ インスタンスとプロキシ プロパティの呼び出しチェーンを Querydsl 式に変換できます。
import com.mysema.query.alias.Alias._
import com.mysema.query.types.expr._
import com.mysema.query.types.path._
object Conversions {
def not(b: EBoolean): EBoolean = b.not()
implicit def booleanPath(b: Boolean): PBoolean = $(b);
implicit def stringPath(s: String): PString = $(s);
implicit def datePath(d: java.sql.Date): PDate[java.sql.Date] = $(d);
implicit def dateTimePath(d: java.util.Date): PDateTime[java.util.Date] = $(d);
implicit def timePath(t: java.sql.Time): PTime[java.sql.Time] = $(t);
implicit def comparablePath(c: Comparable[_]): PComparable[_] = $(c);
implicit def simplePath(s: Object): PSimple[_] = $(s);
}
今、私はこのような式を構築することができます
import com.mysema.query.alias.Alias._
import com.mysema.query.scala.Conversions._
var user = alias(classOf[User])
var predicate = (user.firstName like "Bob") or (user.firstName like "Ann")
以下の問題で悩んでいます。
eq
Scala のメソッドとして既に利用可能でne
あるため、それらが使用されても変換はトリガーされません。
この問題は、次のように一般化できます。eq、ne、startsWith などの Scala 型で既に使用可能なメソッド名を使用する場合、暗黙の変換をトリガーするためにある種のエスケープを使用する必要があります。
以下を検討しています
大文字
var predicate = (user.firstName LIKE "Bob") OR (user.firstName LIKE "Ann")
これは、たとえばCircumflex ORMのアプローチです。これは、同様の DSL の目的を持つ Scala 用の非常に強力な ORM フレームワークです。しかし、このアプローチは、Querydsl では小文字であるクエリ キーワード (select、from、where など) と矛盾します。
いくつかのプレフィックス
var predicate = (user.firstName :like "Bob") :or (user.firstName :like "Ann")
述語使用のコンテキストは次のようなものです
var user = alias(classOf[User])
query().from(user)
.where(
(user.firstName like "Bob") or (user.firstName like "Ann"))
.orderBy(user.firstName asc)
.list(user);
Scala の SQL DSL を構築するためのより良いオプションや別のアプローチはありますか?
したがって、質問は基本的に2つのケースに要約されます
スーパークラスに存在するメソッドを使用するときに暗黙的な型変換をトリガーすることは可能ですか (例
eq
)それが不可能な場合、 , のようなメソッドに使用する最も Scalaesque な構文は何でしょう
eq
かne
?
編集
エイリアス インスタンスと $-prefix ベースのエスケープ構文を使用して、Querydsl で Scala をサポートしました。結果に関するブログ投稿は次のとおりです。http://blog.mysema.com/2010/09/querying-with-scala.html