我想通过跳过第一个 N 元素来更新这个普通的 sql 查询。但这是非常特定于数据库的。
由于您担心更改不同数据库的 SQL,我建议您抽象出这部分 SQL,并根据所使用的 Slick 配置文件决定要做什么。
如果您正在使用多个数据库产品,您可能已经从任何特定配置文件中抽象出来,可能使用了JdbcProfile。在这种情况下,您可以将“跳过 N 个元素”助手放在一个类中,并使用活动的 slickProfile 来决定要使用的 SQL。 (作为替代方案,您当然可以通过其他方式进行检查,例如您设置的环境值)。
实际上可能是这样的:
case class Paginate(profile: slick.jdbc.JdbcProfile) {
// Return the correct LIMIT/OFFSET SQL for the current Slick profile
def page(size: Int, firstRow: Int): String =
if (profile.isInstanceOf[slick.jdbc.H2Profile]) {
s"LIMIT $size OFFSET $firstRow"
} else if (profile.isInstanceOf[slick.jdbc.MySQLProfile]) {
s"LIMIT $firstRow, $size"
} else {
// And so on... or a default
// Danger: I've no idea if the above SQL is correct - it's just placeholder
???
}
}
你可以用作:
// Import your profile
import slick.jdbc.H2Profile.api._
val paginate = Paginate(slickProfile)
val action: DBIO[Seq[Int]] =
sql""" SELECT cols FROM table #${paginate.page(100, 10)}""".as[Int]
通过这种方式,您可以在一个地方隔离(和控制)特定于 RDBMS 的 SQL。
为了使助手更有用,并且由于 slickProfile 是隐式的,您可以改为:
def page(size: Int, firstRow: Int)(implicit profile: slick.jdbc.JdbcProfile) =
// Logic for deciding on SQL goes here
我觉得有必要评论一下,如果用户提供了任何值,那么在普通 SQL 中使用拼接 (#$) 会使您面临 SQL 注入攻击。