SQL与Slick的对比
来源:https://scala-slick.org/doc/3.2.3/sql-to-slick.html
This section shows an overview over the most important types of SQL queries and a corresponding type-safe Slick query.
SELECT *
SQL
Slick
The Slick equivalent of SELECT *
is the result
of the plain TableQuery:
SELECT
SQL
Slick
Scala’s equivalent for SELECT
is map
. Columns can be referenced similarly and functions operating on columns can be accessed using their Scala equivalents (but allowing only ++
for String concatenation, not +
).
.. index:: WHERE, filter, or, and, &&, ||, ==
WHERE
SQL
Slick
Scala’s equivalent for WHERE
is filter
. Make sure to use ===
instead of ==
for comparison.
ORDER BY
SQL
Slick
Scala‘s equivalent for ORDER BY
is sortBy
. Provide a tuple to sort by multiple columns. Slick’s .asc
and .desc
methods affect the ordering. Be aware that a single ORDER BY
with multiple columns is not equivalent to multiple .sortBy
calls but to a single .sortBy
call passing a tuple.
Aggregations (max, etc.)
SQL
Slick
Aggregations are collection methods in Scala. In SQL they are called on a column, but in Slick they are called on a collection-like value e.g. a complete query, which people coming from SQL easily trip over. They return a scalar value, which can be run individually. Aggregation methods such as max
that can return NULL
return Options in Slick.
GROUP BY
People coming from SQL often seem to have trouble understanding Scala‘s and Slick’s groupBy
, because of the different signatures involved. SQL‘s GROUP BY
can be seen as an operation that turns all columns that weren’t part of the grouping key into collections of all the elements in a group. SQL requires the use of its aggregation operations like avg
to compute single values out of these collections.
SQL
Slick
Scala’s groupBy returns a Map of grouping keys to Lists of the rows for each group. There is no automatic conversion of individual columns into collections. This has to be done explicitly in Scala, by mapping from the group to the desired column, which then allows SQL-like aggregation.
SQL requires aggregation of grouped values. We require the same in Slick for now. This means a groupBy
call must be followed by a map
call or will fail with an Exception. This makes Slick‘s grouping syntax a bit more complicated than SQL’s.
HAVING
SQL
Slick
Slick does not have different methods for WHERE
and HAVING
. For achieving semantics equivalent to HAVING
, just use filter
after groupBy
and the following map
.
Implicit inner joins
SQL
Slick
Slick generates SQL using implicit joins for flatMap
and map
or the corresponding for-expression syntax.
Explicit inner joins
SQL
Slick
Slick offers a small DSL for explicit joins.
Outer joins (left/right/full)
SQL
Slick
Outer joins are done using Slick’s explicit join DSL. Be aware that in case of an outer join SQL changes the type of outer joined, non-nullable columns into nullable columns. In order to represent this in a clean way even in the presence of mapped types, Slick lifts the whole side of the join into an Option
. This goes a bit further than the SQL semantics because it allows you to distinguish a row which was not matched in the join from a row that was matched but already contained nothing but NULL values.
Subquery
SQL
Slick
Slick queries are composable. Subqueries can be simply composed, where the types work out, just like any other Scala code.
The method .in
expects a sub query. For an in-memory Scala collection, the method .inSet
can be used instead.
Scalar value subquery / custom function
SQL
Slick
This code shows a subquery computing a single value in combination with a user-defined database function.
insert
SQL
Slick
Inserts can be a bit surprising at first, when coming from SQL, because unlike SQL, Slick re-uses the same syntax that is used for querying to select which columns should be inserted into. So basically, you first write a query and instead of creating an Action that gets the result of this query, you call +=
on with value to be inserted, which gives you an Action that performs the insert. ++=
allows insertion of a Seq of rows at once. Columns that are auto-incremented are automatically ignored, so inserting into them has no effect. Using forceInsert
allows actual insertion into auto-incremented columns.
update
SQL
Slick
Just like inserts, updates are based on queries that select and filter what should be updated and instead of running the query and fetching the data .update
is used to replace it.
delete
SQL
Slick
Just like inserts, deletes are based on queries that filter what should be deleted. Instead of getting the query result of the query, .delete
is used to obtain an Action that deletes the selected rows.
CASE
SQL
Slick
Slick uses a small DSL to allow CASE
like case distinctions.
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
2018-04-27 Debug.Assert vs Exception Throwing(转载)