1. 程式人生 > >springboot結合mybatis使用pageHelper插件進行分頁查詢

springboot結合mybatis使用pageHelper插件進行分頁查詢

oca true else get -a lse enc executor map

1、pom相關依賴引入

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
</dependencies>

2、application配置

# MyBatis
mybatis:
    #數據庫映射對象包路徑
    type-aliases-package: com.example.springbootpagehelper.domain
    #mapper對應xml路徑
    mapper-locations: classpath:/mybatis/*.xml
    #sql打印配置
    configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# PageHelper分頁插件配置
pagehelper:
    #分頁插件會自動檢測當前的數據庫鏈接,自動選擇合適的分頁方式。
    helper-dialect: mysql
    #分頁合理化參數,默認值為false。當該參數設置為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最後一頁。默認false 時,直接根據參數進行查詢。
    reasonable: true
    #支持通過 Mapper 接口參數來傳遞分頁參數,默認值false,分頁插件會從查詢方法的參數值中,自動根據上面 params 配置的字段中取值,查找到合適的值時就會自動分頁。
    support-methods-arguments: true
    #為了支持startPage(Object params)方法,增加了該參數來配置參數映射,用於從對象中根據屬性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認值, 默認值為pageNum=pageNum。
    params: count=countSql

3、代碼編寫分頁查詢

  @Autowired
    private UserService userService;

    @RequestMapping(value = "listUser")
    public List<User> listUser(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageNum) {
        //分頁查詢,包括分頁和總數查詢,第三個參數是控制是否計算總數,默認是true,true為查詢總數,分頁效果只對其後的第一個查詢有效。
        PageHelper.startPage(pageNo, pageNum);
        //有分頁
        List<User> userList = userService.listUser();
        //沒分頁
        List<User> users = userService.listUser();

        return userList;
    }

對返回結果用PageInfo進行封裝

  @RequestMapping(value = "pageInfoUser")
    public PageInfo<User> pageInfoUser(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageNum) {
        //分頁查詢,包括分頁和總數查詢,第三個參數是控制是否計算總數,默認是true,true為查詢總數,分頁效果只對其後的第一個查詢有效。
        PageHelper.startPage(pageNo, pageNum);

        PageInfo<User> userPageInfo = userService.pageInfoUser();

        return userPageInfo;
    }

UserService類

@Override
public PageInfo<User> pageInfoUser() {
     return new PageInfo<>(userMapper.selectUserPage());
}

4、分頁安全性問題

PageHelper 方法使用了靜態的 ThreadLocal 參數,分頁參數和線程是綁定的。

一般只要保證在 PageHelper 方法調用後緊跟 MyBatis 查詢方法,這就是安全的。因為 PageHelper 在 finally 代碼段中自動清除了 ThreadLocal 存儲的對象。

如果代碼在進入 Executor 前發生異常,就會導致線程不可用,導致 ThreadLocal 參數被錯誤的使用。

下面這樣的代碼是不安全的用法:

PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

這種情況下由於 param1 存在 null 的情況,就會導致 PageHelper 生產了一個分頁參數,但是沒有被消費,這個參數就會一直保留在這個線程上。當這個線程再次被使用時,就可能導致不該分頁的方法去消費這個分頁參數,這就產生了錯誤的分頁。

應該寫成下面這個樣子:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

或者可以手動清理 ThreadLocal 存儲的分頁參數,如下所示:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    try{
        list = countryMapper.selectAll();
    } finally {
        PageHelper.clearPage();
    }
} else {
    list = new ArrayList<Country>();
}

源碼參照:【Springboot使用PageHelper插件進行分頁查詢】

springboot結合mybatis使用pageHelper插件進行分頁查詢