简体   繁体   中英

Are parameters of type List or Set in Slick Query Templates possible? (Lifted API)

Is it possible to use collections as Parameters in precompiled Slick queries?

Something like:

private val findByIds = for {
  ids <- Parameters[Set[Int]]
  meta <- AssetMetadatas if meta.id inSet ids
} yield meta

Unfortunately the above does not compile:

Don't know how to unpack scala.collection.immutable.Set[Int] to scala.collection.immutable.Set[Int] and pack to Any ids <- Parameters[Set[Int]] ^

You can't precompile queries using inSet at the moment, neither in Slick 1 nor in Slick 2. It makes sense when you think about that the queries have to be different in SQL for different Set sizes.

  • for 0: WHERE false
  • for 1: WHERE id = ?
  • for 2: WHERE id IN (?,?)
  • for 3: WHERE id IN (?,?,?)
  • ...

This can't be pre-compiled in general, so Slick has to compile the SQL for it every time. We may be able to support it for some backends at some point. If it is important you can precompile a couple of queries for a selected set sizes yourself (using && and == instead of inSet ).

Using inSetBind instead of inSet will pass the set as arguments to a prepared statement instead of compiling them as literals into the SQL string. This allows your connection pool to cache the prepared statements, if you configured it that way. So Slick will still have to compile the query, but at least your db can cache the query plan.

There's inSetBind for that:

private def findByIds(ids: Set[Int]) = for {
  meta <- AssetMetadatas if meta.id inSetBind ids
} yield meta

Yes, this will invoke the query compiler each time you call findByIds , but it will always yield the same SQL for the same cardinality of ids .

So for ids of Set(1,2,3) the resulting SQL will be generated,

SELECT * from AssetMetadatas WHERE ID IN (?, ?, ?)

And will be bound to (1, 2, 3) when the query is invoked. The query compiler will run again when you call findByIds(Set(4,5,6)) but the exact same SQL will be generated. Even assuming slick does not cache the compiled AST result, that's still a small cost compared to the savings at the database level (using bind parameters).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM