您想要分页,但不想将未分页的结果集 O(n) 加载到内存中。足够公平 - 从逻辑上讲,这意味着数据库必须将分页块交给您。我认为大多数 RDMS 数据库都有类似“LIMIT”和“OFFSET”的 SQL:
select id, name from foo where date > ? LIMIT $start, $page_size;
如果您正在处理 MySQL,并且正在编写原始 SQL,那么它将是这样的。但是对于像 Slick 这样的库,你可以拥有
val query = for {
d <- Parameter[Date]
f <- foo if f.date > d
} yield (f.id, f.name)
所以要让所有行取消分页
query(yesterday).list
// Select id, name from foo
如果你想要分页,很简单:
query(yesterday).drop(20).take(5).list
// Select id, name from foo limit 20, 5 ; %% whatever; I suck at SQL and can't remember syntac
%% but you get the point.
这将返回一个包含 5 个元素的 (Id, Name) 列表,假设您每页只需要 5 个元素。这意味着该子序列将是结果的第 5 页。
如果不是query(yesterday) 你在内存中有一个List 的结果,这不是你可能会做的:SLICK 为你提供了一个查询抽象,一个Query 类型
包含许多通常在集合中找到的有用方法。 .list 方法实际上是执行最终查询以获得List[T](在此示例中为List[(Int, String)]),但在调用它之前,您可以“分页”您的结果(通过调用.take、drop 等,构建 uopn 原始查询),在此示例中,SQL 为您执行分页
SLICK 会生成该 SQL,因此您只需执行 .take、.drop 或其他操作。
如果您的模型层利用 SLICK 的可组合性会有所帮助:您定义
SLICK 中的基本查询,而不是编写原始 SQL,这些查询可用作其他查询的构建块。