Scala Slick:筛选joda DateTime日期等于今天的所有记录
实现这一目标的一种方法是:Scala Slick:筛选joda DateTime日期等于今天的所有记录,scala,jodatime,slick,Scala,Jodatime,Slick,实现这一目标的一种方法是: val now = DateTime.now val today = now.toLocalDate val tomorrow = today.plusDays(1) val startOfToday = today.toDateTimeAtStartOfDay(now.getZone) val startOfTomorrow = tomorrow.toDateTimeAtStartOfDay(now.getZone) val todayLogItems = l
val now = DateTime.now
val today = now.toLocalDate
val tomorrow = today.plusDays(1)
val startOfToday = today.toDateTimeAtStartOfDay(now.getZone)
val startOfTomorrow = tomorrow.toDateTimeAtStartOfDay(now.getZone)
val todayLogItems = logItems.filter(logItem =>
logItem.MyDateTime >= startOfToday && logItem.MyDateTime < startOfTomorrow
).list
我这样问是因为在LINQ to NHibernate中,这是可以实现的()。使用LocalDateTimes而不是直接使用LocalDates会让事情变得混乱:
val today = LocalDate.now
val todayLogItems = logItems.filter(_.MyDateTime.toLocalDate isEqual today)
更新
这里需要对这个问题做一个主要的澄清,Slick只是顺便提到的,只是作为一个标签
然而。。。Slick是这个问题的核心,这取决于filter
操作实际上是通过
我对该库不太熟悉,但这肯定意味着您仅限于可以在SQL中执行的操作。由于这是一列[DateTime],因此必须将其与另一个DateTime进行比较
至于LINQ示例,它似乎建议首先获取所有内容,然后按照上面的示例进行操作(在Scala中执行比较,而不是在SQL中执行比较)。这是一种选择,但我怀疑您不会想要它带来的性能成本
更新2(只是澄清一下)
没有答案
无法保证您的底层数据库能够在日期和时间戳之间进行平等性检查,因此slick不能依赖现有的这种能力
你被困在岩石和坚硬的地方之间。要么像现在一样在时间戳之间进行范围检查,要么从查询中提取所有内容并在Scala中进行过滤——这可能会带来沉重的性能代价
最终更新
关于你提到的Linq/NHibernate问题,这里有几句话:
- 您还可以通过SqlFunction使用Criteria中的日期函数
- 这取决于LINQ提供程序
- 我不确定NHibernate LINQ提供商是否支持
- 依靠NHibernate将日期强制逻辑推送到数据库中,如果不可能,可能会默默地削弱性能(通过获取所有记录并在本地进行过滤)
- 依赖您编写自定义SQL逻辑
- 将列拆分为单独的日期/时间列
- 将日期添加为计算列(可能在视图中)
- 使用自定义SQL(或存储过程)进行查询
- 坚持范围检查
- 使用辅助函数
def equalsDate(dt: LocalDate) = {
val start = dt.toDateTimeAtStartOfDay()
val end = dt.plusDays(1).toDateTimeAtStartOfDay()
(col: Column[DateTime]) => {
col >= start && col < end
}
}
val isToday = equalsDate(LocalDate.now)
val todayLogItems = logItems.filter(x => isToday(x.MyDateTime))
def equalsDate(dt:LocalDate)={
val start=dt.toDateTimeAtStartOfDay()
val end=dt.plusDays(1).toDateTimeAtStartOfDay()
(列[DateTime])=>{
列>=开始和列<结束
}
}
val isToday=equalsDate(LocalDate.now)
val todayLogItems=logItems.filter(x=>isToday(x.MyDateTime))
除非精巧的joda mapper添加了对比较的支持,否则除非您自己添加,否则您的运气就不好了。为了给它一个机会,这些可能是有用的提示:
*
*
*
我创建了一个ticket,以便在某个时候在Slick中查看它:这不起作用,因为
.MyDateTime
没有toLocalDate
方法,因为它属于列[Imports.DateTime]
。我正在导入导入com.github.tototoshi.slick.H2JodaSupport.\u
来自https://github.com/tototoshi/slick-joda-mapper
,这使得它可以像我的示例中使用的那样工作。但是访问MyDateTime的成员是不起作用的。将slick
作为标记和问题中的第二个示例(这不起作用,但如果它只在内存中运行就会起作用)足以清楚地说明问题上下文是什么。对不起,我不能投票或接受你的答案,因为它不能回答问题。如果没有答案,就没有问题。仅仅为了在内存中查询而从数据库中检索所有数据并不是一个解决方案,因为可以使用问题中提到的方法在数据库中进行查询,而不会受到任何惩罚。数据库只需要支持时间戳比较,LINQ可以在不考虑数据库的情况下执行该查询,这证明了Slick也可以这样做。无论如何,+1表示感谢。别忘了用===代替==
def equalsDate(dt: LocalDate) = {
val start = dt.toDateTimeAtStartOfDay()
val end = dt.plusDays(1).toDateTimeAtStartOfDay()
(col: Column[DateTime]) => {
col >= start && col < end
}
}
val isToday = equalsDate(LocalDate.now)
val todayLogItems = logItems.filter(x => isToday(x.MyDateTime))