很多人都知道PageHelper怎么使用,如果不知道在百度搜一下也会出现很多结果。
可是在项目里引入了PageHelper,很少有人知道怎么不使用它。
如果你在查看sql报错,发现自己的代码中使用的查询sql被无缘无故添加了“PageHelper”,是不是该想知道该如何不使用PageHelper呢?
在项目中使用了pagehelper,总是莫名其妙的出现sql报警,由于使用了LIMIT ?导致的limit重复或是在“;”多了“LIMIT ?”。
1.只会在使用PageHelper之后才会在sql中自动添加LIMIT ?,初步定位为pageHelper使用错误。
2.查看pageHelper源码,发现使用了 PageInterceptor 过滤器。只有在执行sql查询的时候才会执行。
3.当在方法中添加了 PageHelper.startPage(curPage, perPage); 但是在后面没有使用到,就会被遗留到该线程下一次执行sql查询。
4.由于tomcat使用线程池管理,所以,下一次复用该线程的时候就可能存在问题。
(前提:要尽量全的打印日志,其中必须包括线程号)
1.写两个controller,第一个controller里面只有PageHelper.startPage(curPage, perPage); 第二个controller只有查询sql,并且改sql包含limit (包含了limit的sql如果被添加LIMIT ?后会报异常,方便跟踪)。
2.启动程序,第一次调用第一个controller了,记录执行线程号。
3.不断的刷新第二个controller,直到报异常。查看报异常线程号。
3.验证两个线程号是不是同一个线程
根据上述推断查找线上日志。
1.查找到报异常日志所在服务器,以及相应的request_id。(request_id:是每个请求唯一的序列号,以识别该请求的所有处理过程)
2.根据request_id到相应服务器查找对应的线程号,例如此处为“http-nio-8311-exec-9”
3.根据线程号和request_id查找该请求之前的请求处理。
cat xinche-deal-agency-manager-2019-07-02.log | grep 'http-nio-8311-exec-9' | grep -B100 'ed7b53fb-d08f-44ad-8e7e-e4e955c5927c'
4.定位到紧上一次处理的类和方法,分析该方法,查找是否存在写了PageHelper.startPage(curPage, perPage); 但没有执行的情况。
例如:
Int deptId = getDeptId();
PageHelper.startPage(1,10);
List objs = null;
If(deptId == 1){
objs = mapper.getObjs1();
}else{
List list = service.getObject2s();
If(list.size() > 0){
objs = mapper.getObjs2();
}else{
objs = new ArrayList();
}
}
1.增加filter
@WebFilter()
public class CommonFilter implements Filter{
/* (non-Javadoc)
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
//清空pagehelper
PageHelper.clearPage();
}
/* (non-Javadoc)
* @see javax.servlet.Filter#destroy()
*/
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
2.修改上面的方法
Int deptId = getDeptId();
List objs = null;
If(deptId == 1){
PageHelper.startPage(1,10);
objs = mapper.getObjs1();
}else{
List list = service.getObject2s();
If(list.size() > 0){
PageHelper.startPage(1,10);
objs = mapper.getObjs2();
}else{
objs = new ArrayList();
}
}
1.将使用不当的方法进行修改,规范代码及正确使用PageHelper.startPage(1,10);
2.对于所有请求使用filter处理,以免有使用出错之处。
3.对于异步任务或是kafka,使用filter并不能处理,将错误方法修改更正即可。