1. 程式人生 > 其它 >分頁和註解開發

分頁和註解開發

4. 分頁

4.1 使用Limit進行分頁

List<User> selectByLimit(Map<String,Integer> map);
<select id="selectByLimit" parameterType="map" resultType="user">
    select * from user limit #{startIndex},#{pageSize}
</select>
SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
HashMap<String,Integer> map = new HashMap<>();
map.put("startIndex",1);
map.put("pageSize",2);
final List<User> users = mapper.selectByLimit(map);
System.out.println(users);
sqlSession.close();

4.2 分頁外掛PageHelper

官方參考:https://pagehelper.github.io/

1.匯入PageHelper依賴

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

2.配置分頁外掛

在 MyBatis 配置 xml 中配置攔截器外掛

<!--
    plugins在配置檔案中的位置必須符合要求,否則會報錯,順序如下:
    properties?, settings?,
    typeAliases?, typeHandlers?,
    objectFactory?,objectWrapperFactory?,
    plugins?,
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置引數,後面會有所有的引數介紹 -->
        <property name="param1" value="value1"/>
	</plugin>
</plugins>

在 Spring 配置檔案中配置攔截器外掛

使用 spring 的屬性配置方式,可以使用 plugins 屬性像下面這樣配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <!-- 注意其他配置 -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置引數,一行配置一個 -->
          <value>
            params=value1
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>

配置檔案引數介紹

分頁外掛提供了多個可選引數,這些引數使用時,按照上面兩種配置方式中的示例配置即可。

分頁外掛可選引數如下:

  • dialect:預設情況下會使用 PageHelper 方式進行分頁,如果想要實現自己的分頁邏輯,可以實現 Dialect(com.github.pagehelper.Dialect) 介面,然後配置該屬性為實現類的全限定名稱。

下面幾個引數都是針對預設 dialect 情況下的引數。使用自定義 dialect 實現時,下面的引數沒有任何作用。

  1. helperDialect:分頁外掛會自動檢測當前的資料庫連結,自動選擇合適的分頁方式。 你可以配置helperDialect屬性來指定分頁外掛使用哪種方言。配置時,可以使用下面的縮寫值:
    oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
    特別注意:使用 SqlServer2012 資料庫時,需要手動指定為 sqlserver2012,否則會使用 SqlServer2005 的方式進行分頁。
    你也可以實現 AbstractHelperDialect,然後配置該屬性為實現類的全限定名稱即可使用自定義的實現方法。
  2. offsetAsPageNum:預設值為 false,該引數對使用 RowBounds 作為分頁引數時有效。 當該引數設定為 true 時,會將 RowBounds 中的 offset 引數當成 pageNum 使用,可以用頁碼和頁面大小兩個引數進行分頁。
  3. rowBoundsWithCount:預設值為false,該引數對使用 RowBounds 作為分頁引數時有效。 當該引數設定為true時,使用 RowBounds 分頁會進行 count 查詢。
  4. pageSizeZero:預設值為 false,當該引數設定為 true 時,如果 pageSize=0 或者 RowBounds.limit = 0 就會查詢出全部的結果(相當於沒有執行分頁查詢,但是返回結果仍然是 Page 型別)。
  5. reasonable:分頁合理化引數,預設值為false。當該引數設定為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最後一頁。預設false 時,直接根據引數進行查詢。
  6. params:為了支援startPage(Object params)方法,增加了該引數來配置引數對映,用於從物件中根據屬性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置對映的用預設值, 預設值為pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
  7. supportMethodsArguments:支援通過 Mapper 介面引數來傳遞分頁引數,預設值false,分頁外掛會從查詢方法的引數值中,自動根據上面 params 配置的欄位中取值,查詢到合適的值時就會自動分頁。 使用方法可以參考測試程式碼中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTestArgumentsObjTest
  8. autoRuntimeDialect:預設值為 false。設定為 true 時,允許在執行時根據多資料來源自動識別對應方言的分頁 (不支援自動選擇sqlserver2012,只能使用sqlserver),用法和注意事項參考下面的場景五
  9. closeConn:預設值為 true。當使用執行時動態資料來源或沒有設定 helperDialect 屬性自動獲取資料庫型別時,會自動獲取一個數據庫連線, 通過該屬性來設定是否關閉獲取的這個連線,預設true關閉,設定為 false 後,不會關閉獲取的連線,這個引數的設定要根據自己選擇的資料來源來決定。

重要提示:

offsetAsPageNum=false 的時候,由於 PageNum 問題,RowBounds查詢的時候 reasonable 會強制為 false。使用 PageHelper.startPage 方法不受影響。

3.使用

分頁外掛支援以下幾種呼叫方式:

//第一種,RowBounds方式的呼叫
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));

//第二種,Mapper介面方式的呼叫,推薦這種使用方式。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);

//第三種,Mapper介面方式的呼叫,推薦這種使用方式。
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);

//第四種,引數方法呼叫
//存在以下 Mapper 介面方法,你不需要在 xml 處理後兩個引數
public interface CountryMapper {
    List<Country> selectByPageNumSize(
            @Param("user") User user,
            @Param("pageNum") int pageNum,
            @Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在程式碼中直接呼叫:
List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10);

//第五種,引數物件
//如果 pageNum 和 pageSize 存在於 User 物件中,只要引數有值,也會被分頁
//有如下 User 物件
public class User {
    //其他fields
    //下面兩個引數名和 params 配置的名字一致
    private Integer pageNum;
    private Integer pageSize;
}
//存在以下 Mapper 介面方法,你不需要在 xml 處理後兩個引數
public interface CountryMapper {
    List<Country> selectByPageNumSize(User user);
}
//當 user 中的 pageNum!= null && pageSize!= null 時,會自動分頁
List<Country> list = countryMapper.selectByPageNumSize(user);

//第六種,ISelect 介面方式
//jdk6,7用法,建立介面
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectGroupBy();
    }
});
//jdk8 lambda用法
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());

//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectGroupBy();
    }
});
//對應的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());

//count查詢,返回一個查詢語句的count數
long total = PageHelper.count(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectLike(country);
    }
});
//lambda
total = PageHelper.count(()->countryMapper.selectLike(country));
SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
PageHelper.startPage(1, 2);
List<User> all = userDao.getAll();
System.out.println(((Page)all).getTotal());
System.out.println(((Page)all).getPages());
System.out.println(((Page)all).getStartRow());
System.out.println(((Page)all).getEndRow());
for (User user : all) {
    System.out.println(user);
}
sqlSession.close();
List<User> selectByPageNumSize(@Param("pageNumKey") int pageNum,@Param("pageSizeKey") int pageSize);

SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> users = userDao.selectByPageNumSize(2,3);
PageInfo info = new PageInfo(users);
System.out.println(info.getPages());
System.out.println(info.getPageSize());
System.out.println(info.getStartRow());
System.out.println(info.getEndRow());
System.out.println(info.getPageNum());
System.out.println(info.getNavigateFirstPage());
System.out.println(info.getNavigateLastPage());
System.out.println(info.isHasPreviousPage());
System.out.println(info.isHasNextPage());

for (User user : users) {
    System.out.println(user);
}
sqlSession.close();

5.註解

使用註解進行CURD操作

@Select("select * from user where id = #{id}")
User selectById(@Param("id") int id);

@Insert("insert into user(id,name,pwd) values(#{id},#{name},#{password})")
int Insert(User user);
@Update("update user set name = #{name} ,pwd = #{password} where id = #{id}")
int Update(User user);
@Delete("delete from user where id = #{id}")
int Delete(@Param("id") int id);

在核心配置檔案中註冊介面

<mapper class="com.wyz.dao.UserDao"/>

在有多個基本型別或者String的時候,可以使用@Param對引數進行標記。引用型別不用標記。