Я изучаю различные возможности по внедрению общего DAO с использованием новейшего Slick 3.1.1 для повышения производительности и да, это необходимо для него, потому что базовый уровень сервиса моего приложения Play Web на TableQuery
приводит только к большому шаблону кода , Одним из методов, которые я хотел бы включить в мою общую реализацию DAO, является findByExample
, возможный в JPA с помощью Criteria API. В моем случае я использую Slick Code Generator для генерации классов модели из SQL-скрипта.Слайк: как реализовать поиск по примеру i.e. findByExample в общем?
мне нужно следующее, чтобы иметь возможность динамического доступа имена атрибутов, взятые из Scala. Get field names list from case class:
import scala.reflect.runtime.universe._
def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor => m
}.toList
Проект реализации для findByExample
будет:
def findByExample[T, R](example: R) : Future[Seq[R]] = {
var qt = TableQuery[T].result
val accessors = classAccessors[R]
(0 until example.productArity).map { i =>
example.productElement(i) match {
case None => // ignore
case 0 => // ignore
// ... some more default values => // ignore
// handle a populated case
case Some(x) => {
val columnName = accessors(i)
qt = qt.filter(_.columnByName(columnName) == x)
}
}
}
qt.result
}
Но это не работает потому что мне нужно лучше Scala Kungfu. T
- тип таблицы сущностей, а R
- тип строки, который генерируется как класс case и, следовательно, действительный тип Scala Product
.
Первой проблемой в этом коде является то, что было бы слишком неэффективно, потому что вместо того, чтобы делать, например,
qt.filter(_.firstName === "Juan" && _.streetName === "Rosedale Ave." && _.streetNumber === 5)
делает:
// find all
var qt = TableQuery[T].result
// then filter by each column at the time
qt = qt.filter(_.firstName === "Juan")
qt = qt.filter(_.streetName === "Rosedale Ave.")
qt = qt.filter(_.streetNumber === 5)
Во-вторых, я не могу видеть, как динамически получать доступ к имени столбца в методе фильтра т.е.
qt.filter(_.firstName == "Juan")
мне нужно вместо этого
qt.filter(_.columnByName("firstName") == "Juan")
, но, по-видимому, e нет такой возможности при использовании функции filter
?