项目有sql查询,查询1条记录的sql:select * from xxx where xxx='a' limit 1;
但是在执行的时候出现sql异常:
### The error occurred while setting parameters
### SQL: select * from xxx where xxx = ? limit 1 LIMIT 10
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax;
关键异常栈打印
at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:134)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
at com.sun.proxy.$Proxy194.query(Unknown Source)
初步怀疑是PageInterceptor插件给sql后追加了limit 10,但是我们方法内没有调用
PageHelper.startPage,为什么还会追加limit 10?
只能一步步debug,发现PageInterceptor类dialect.skip方法内部会调
PageParams类,里面有段逻辑
Page page = PageHelper.getLocalPage();
if (page == null) {
if (rowBounds != RowBounds.DEFAULT) {
if (offsetAsPageNum) {
page = new Page(rowBounds.getOffset(), rowBounds.getLimit(), rowBoundsWithCount);
} else {
page = new Page(new int[]{rowBounds.getOffset(), rowBounds.getLimit()}, rowBoundsWithCount);
//offsetAsPageNum=false的时候,由于PageNum问题,不能使用reasonable,这里会强制为false
page.setReasonable(false);
}
} else {
try {
page = PageObjectUtil.getPageFromObject(parameterObject, false); // 重点是这块
} catch (Exception e) {
return null;
}
}
if(page == null){
return null;
}
PageHelper.setLocalPage(page); // 会往threadlocal里放入page对象,所以一开始在我们调用方法的入口新增PageHelper.clear也不管用,此处会重现放入分页对象
}
PageObjectUtil的getPageFromObject片段代码
try {
Object _pageNum = getParamValue(paramsObject, "pageNum", required); // 会从入参对象获取pageNum,pageSize,如果有就会分页
Object _pageSize = getParamValue(paramsObject, "pageSize", required);
if (_pageNum == null || _pageSize == null) {
return null;
}
pageNum = Integer.parseInt(String.valueOf(_pageNum));
pageSize = Integer.parseInt(String.valueOf(_pageSize));
} catch (NumberFormatException e) {
throw new PageException("分页参数不是合法的数字类型!");
}
Page page = new Page(pageNum, pageSize);
刚好sql的入参对象有同事新增了这2个变量,导致这次sql异常
总结:sql的插件还是尽量避免使用,sql还是控制在自己手上好,毕竟框架考虑通用性就会牺牲性能,对框架不熟悉也会带来不必要的麻烦