PageHelper問題--sql被添加了LIMIT ?

很多人都知道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<Object1> objs = null;

If(deptId == 1){

  objs = mapper.getObjs1();

}else{

  List<Object2> 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<Object1> objs = null;

If(deptId == 1){

  PageHelper.startPage(1,10);

  objs = mapper.getObjs1();

}else{

  List<Object2> 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並不能處理,將錯誤方法修改更正即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章