我正在尝试使用jOOQ(3.11.12)+ MySQL(5.7.24)实现“搜索”分页。
我有一个产品表,其中包含以下行:
ID | Name | Created At
---------------------- --------- -------------------
XjpPXlZxT5i3tTjO7lZQ6Q Product A 2019-10-25 03:23:05
SmytEB9lTW-UiVFhg_gViQ Product B 2019-10-09 05:43:44
glpNYcsBTJqAzQERbgGh5g Product C 2019-10-02 14:53:48
HDZ1K7g_Rj-2vdQaEj79Ow Product D 2019-09-07 14:52:56
aTcWWxdJSReZBGzkLXuNIQ Product E 2019-09-06 08:21:24
HPOD380mTR-g2Ut4Da0k4Q Product F 2019-09-06 08:19:57
jXzfHBDAQ6We4CjXLem_WA Product G 2019-09-06 08:16:06
duxiQ3InRXaFy_JVDkkewQ Product H 2019-09-06 08:15:02
QF-3ECfLQD2vdVGE_5X-rQ Product I 2019-09-04 12:35:00
zRnp0tLZRjSsQHN0wV7N_w Product J 2019-09-04 12:34:28
6Y3E3KkITYWbOs5aOQCHOw Product K 2019-09-04 10:33:38
ZOoG06ThRTiDDhteIW_6tA Product L 2019-09-04 10:19:14
6UW4MUClSLSuQI3pkA0qJA Product M 2019-09-04 10:18:40
假设我的应用程序一次显示5个产品的页面,从最新到最旧的顺序。
因此,我按创建日期降序排序,也按ID排序,以便消除可能在同一时间创建的产品之间的歧义。
我正在尝试获取结果,该内容将是第二页。代码(已替换相关的运行时值)如下所示:
selectFromWhere // <-- assume this to be a SelectConditionStep built with various filter criteria
.orderBy(TBL_PRODUCT.CREATED_AT.desc(), TBL_PRODUCT.ID.asc())
.seek(2019-09-06T08:21:24Z, "aTcWWxdJSReZBGzkLXuNIQ") // <-- runtime values
.limit(limit)
.fetchInto(Product::class.java)
这将生成以下SQL(为简洁起见,省略了标准引用和过滤条件):
select distinct
id, created_at
from tbl_product
where (
(
created_at < {ts '2019-09-06 08:21:24.0'}
or (
created_at = {ts '2019-09-06 08:21:24.0'}
and id > 'aTcWWxdJSReZBGzkLXuNIQ'
)
)
)
order by
created_at desc,
id asc
limit 5
如果我从SQL会话中手动复制/粘贴并运行生成的查询,则会得到预期的结果:
...但是,执行结果保存到局部变量中,当我调试程序以检查其内容时,我看到它包含:
两个问题:
任何建议将不胜感激!
答案 0 :(得分:2)
假设TBL_PRODUCT.CREATED_AT
的数据库列类型为DATETIME
,并且相应的Java类型为java.sql.Timestamp
(在jOOQ 3.11中为默认值),则在时区时可能会出现这种情况MySQL服务器的版本与Java客户端的版本不同,因为JDBC驱动程序将为您转换时间戳(有关详细信息,请参见https://stackoverflow.com/a/14070771/1732086)。
也可以使用各种JDBC连接URL参数来控制此行为(请参见https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-configuration-properties.html)。一种选择是使用serverTimezone
JDBC URL属性将客户端的时区指定为要使用的会话时区(例如serverTimezone=Europe/Zurich
)。
时区总会带来令人讨厌的惊喜,尤其是在JDBC的情况下:-(