Scala slick query where in list

后端 未结 4 1368
忘掉有多难
忘掉有多难 2021-02-03 22:57

I am attempting to learn to use Slick to query MySQL. I have the following type of query working to get a single Visit object:

Q.query[(Int,Int), Visit](\"\"\"
          


        
4条回答
  •  粉色の甜心
    2021-02-03 23:12

    It doesn't work because the StaticQuery object (Q) expects to implicitly set the parameters in the query string, using the type parameters of the query method to create a sort of setter object (of type scala.slick.jdbc.SetParameter[T]).
    The role of SetParameter[T] is to set a query parameter to a value of type T, where the required types are taken from the query[...] type parameters.

    From what I see there's no such object defined for T = List[A] for a generic A, and it seems a sensible choice, since you can't actually write a sql query with a dynamic list of parameters for the IN (?, ?, ?,...) clause


    I did an experiment by providing such an implicit value through the following code

    import scala.slick.jdbc.{SetParameter, StaticQuery => Q}
    
    def seqParam[A](implicit pconv: SetParameter[A]): SetParameter[Seq[A]] = SetParameter {  
        case (seq, pp) =>
            for (a <- seq) {
                pconv.apply(a, pp)
            }
    }
    
    implicit val listSP: SetParameter[List[String]] = seqParam[String]
    

    with this in scope, you should be able to execute your code

    val locationCodes = List("loc1","loc2","loc3"...)
    Q.query[(Int,Int,List[String]), Visit]("""
        select * from visit where vistor = ? and location_code in (?,?,?...)
    """).list(visitorId,locationCodes)
    

    But you must always manually guarantee that the locationCodes size is the same as the number of ? in your IN clause


    In the end I believe that a cleaner workaround could be created using macros, to generalize on the sequence type. But I'm not sure it would be a wise choice for the framework, given the aforementioned issues with the dynamic nature of the sequence size.

提交回复
热议问题