我正在尝试使用Spring JPA 2.0.9和Hibernate 5.3.5访问FileMaker 16数据库,使用the official JDBC driver和this dialect进行Hibernate。
我对方言进行了修改,以便它支持限制FileMaker结果集,添加一个限制处理程序,如下所示:
public class FileMakerDialect extends Dialect {
...
private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
public String processSql(String sql, RowSelection selection) {
String soff = " offset ? rows";
String slim = " fetch first ? rows only";
StringBuilder sb = (new StringBuilder(sql.length() + soff.length() + slim.length())).append(sql);
if (LimitHelper.hasFirstRow(selection)) {
sb.append(soff);
}
if (LimitHelper.hasMaxRows(selection)) {
sb.append(slim);
}
return sb.toString();
}
public boolean supportsLimit() {
return true;
}
};
public LimitHandler getLimitHandler() {
return LIMIT_HANDLER;
}
...
}
限制处理程序只是将offset ? rows fetch first ? rows only
添加到select查询的末尾。
现在我尝试从Spring JPA repo获取分页结果时测试失败:
com.filemaker.jdbc.FMSQLException:[FileMaker] [FileMaker JDBC] FQL0001 /(1:338):查询的语法有错误。 com.filemaker.jdbc.FM_API.prepare(未知来源)位于com.filemaker.jdbc.FM_API.prepareRS(未知来源)com.filemaker.jdbc.FM_API.prepareRS(未知来源)com.filemaker.jdbc1.CommonJ1Statement上的com.filemaker.jdbc.FM_API.prepare(未知来源) 。(unknown Source)com.filemaker.jdbc2.CommonJ2Statement。(Unknown Source)at com.filemaker.jdbc3.CommonJ3Statement。(Unknown Source)at com.filemaker.jdbc3.J3PreparedStatement。(Unknown Source)at com.filemaker.jdbc3来自com.zaxxer.hikari.pool的com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:318)中的com.filemaker.jdbc2.CommonJ2Connection.prepareStatement(未知来源)的.J3Connection.prepareStatement(未知来源)。位于org.hibernate.engine.jdbc.internal.StatementPreparerImpl的语言中的org.hibernate.engine.jdbc.internal.StatementPreparerImpl $ 5.doPrepare(StatementPreparerImpl.java:146)中的HikariProxyConnection.prepareStatement(HikariProxyConnection.java)$ StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java :172)......还有87个
但是,如果我从com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:318)
获取类似于select * from "MarketingCategories" marketingc0_ offset ? rows fetch first ? rows only
的SQL,将问号替换为数字并使用相同的驱动程序手动对FileMaker数据库执行,它会成功返回分页结果集。
我该怎么做这个例外?我希望得到一个如何进一步调试它的线索。没有fm jdbc驱动程序的源代码,反编译类也没有行号信息,所以我无法在调试器中检查它。
在报告问题here时,我做了一个解决方法:
public class FileMakerDialect extends Dialect {
...
private static final LimitHandler LIMIT_HANDLER = new AbstractLimitHandler() {
public String processSql(String sql, RowSelection selection) {
String soff = String.format(" offset %d rows /*?*/", selection.getFirstRow());
String slim = String.format(" fetch first %d rows only /*?*/", selection.getMaxRows());
StringBuilder sb = (new StringBuilder(sql.length() + soff.length() + slim.length())).append(sql);
if (LimitHelper.hasFirstRow(selection)) {
sb.append(soff);
}
if (LimitHelper.hasMaxRows(selection)) {
sb.append(slim);
}
return sb.toString();
}
public boolean supportsLimit() {
return true;
}
};
...
}
它将参数绑定的占位符放在注释中,在限制处理程序中插入分页参数。