생산성을 높이기 위해 최신 Slick 3.1.1을 사용하여 제네릭 DAO를 구현하는 방법에 대한 다양한 가능성을 모색 중이며 TableQuery
에있는 내 Play 웹 응용 프로그램의 서비스 계층을 기반으로하면 상용구 코드가 많아지기 때문에 필요합니다. . 내 일반적인 DAO 구현에서 기능을 사용하려는 방법 중 하나는 findByExample
이며 Criteria API을 사용하여 JPA에서 가능합니다. 제 경우에는 Slick Code Generator을 사용하여 SQL 스크립트에서 모델 클래스를 생성합니다.Slick : 예를 들어 findByExample을 일반적으로 구현하는 방법은 무엇입니까?
import scala.reflect.runtime.universe._
def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor => m
}.toList
findByExample
에 대한 초안 구현은 다음과 같습니다 :
는 동적으로 Scala. Get field names list from case class에서 가져온 속성 이름에 액세스 할 수 있도록 다음 필요
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
}
하지만이 작동하지 않습니다 왜냐하면 나는 스칼라 쿵후가 더 필요하기 때문이다. T
은 엔티티 테이블 유형이고 R
은 사례 클래스로 생성 된 행 유형이므로 유효한 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")
하지만 분명히 filter
기능을 사용하는 동안 e는 그런 가능성이 없습니까? 아마