使用 sortBy 方法在 slick 中进行不区分大小写的排序

Case insensitive sorting in slick using sortBy method

<>.sortBy(c => c.Name.asc).take(10)

这种巧妙的排序在 'a' 之前考虑 'Z', 有没有什么可以在 slick 中进行不区分大小写的排序?

控制大小写排序有两种方式:

  • 如果您可以控制数据库列并希望在任何地方强制执行不区分大小写的行为,那么第一个选项很好

  • 如果您只需要在几个受控的地方执行此操作,则第二种选择很好。

1。列排序规则

正如@bmateusz 所说,排序由列的排序规则控制。这可以在您创建或修改列(或 table,或者可能是数据库)时设置。它可能特定于您正在使用的数据库。

考虑到 H2,包含名称 "alice" 和 "Bob" 的 table 默认情况下(在 H2 中)排序为:首先是 "Bob",然后是 "alice".

您可以在定义列时更改它:

case class Message(name: String, id: Long = 0L)

final class MessageTable(tag: Tag) extends Table[Message](tag, "message") {
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name", O.SqlType("VARCHAR_IGNORECASE(255)") )
  def * = (name, id).mapTo[Message]
}

请注意,我指定了特定于 H2 的列类型:VARCHAR_IGNORECASE

运行 这段代码:

val testData = List( Message("alice"), Message("Bob") )

val program = for {
  _ <- messages.schema.create
  _ <- messages ++= testData
  results <- q.sortBy(c => c.name.asc).result
} yield results

val db = Database.forConfig("example")
try Await.result(db.run(program), 2.seconds).foreach(println)
finally db.close

... 将产生顺序:"alice"、"Bob"。

您正在使用的数据库应该有一个页面描述您的排序规则选项。示例包括:

如果您不使用 Slick 来定义您的 tables,您当然可以在 Slick 之外调整排序规则(使用您用来控制模式的任何工具或命令)。

2。更改查询中的大小写

实现不区分大小写排序的一个技巧是更改查询以将文本转换为一种大小写。例如:

val q = messages.sortBy(c => c.name.toLowerCase.asc)

切换为小写应该会有类似的效果。上面的 Slick 查询将按照以下行生成 SQL:

select "name", "id" from "message" order by lcase("name"))