我正在努力为 Scala 创建一个 SQL DSL。DSL 是 Querydsl 的扩展,Querydsl是一种流行的 Java 查询抽象层。
我现在正在努力使用非常简单的表达式,如下所示
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
并且ne
已经在 Scala 中作为方法可用,因此在使用时不会触发转换
这个问题可以概括如下。当使用 Scala 类型中已经可用的方法名称时,例如 eq、ne、startsWith 等,需要使用某种转义来触发隐式转换。
我正在考虑以下
大写
var predicate = (user.firstName LIKE "Bob") OR (user.firstName LIKE "Ann")
例如,Circumflex ORM中的方法,这是一个非常强大的用于 Scala 的 ORM 框架,具有类似的 DSL 目标。但是这种方法会与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 构建,您是否看到了更好的选择或不同的方法?
所以这个问题基本上归结为两种情况
使用超类中存在的方法时是否可以触发隐式类型转换(例如
eq
)如果不可能,那么对于 , 之类的方法使用最 Scalaesque 的语法是
eq
什么ne
?
编辑
通过使用别名实例和基于 $-prefix 的转义语法,我们在 Querydsl 中获得了 Scala 支持。这是关于结果的博客文章:http: //blog.mysema.com/2010/09/querying-with-scala.html