亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Mybatis分頁插件PageHelper的配置和簡單使用方法(推薦)

2024-07-13 10:14:21
字體:
來源:轉載
供稿:網友

前言

在web開發過程中涉及到表格時,例如dataTable,就會產生分頁的需求,通常我們將分頁方式分為兩種:前端分頁和后端分頁。

前端分頁

一次性請求數據表格中的所有記錄(ajax),然后在前端緩存并且計算count和分頁邏輯,一般前端組件(例如dataTable)會提供分頁動作。

特點是:簡單,很適合小規模的web平臺;當數據量大的時候會產生性能問題,在查詢和網絡傳輸的時間會很長。

后端分頁

在ajax請求中指定頁碼(pageNum)和每頁的大小(pageSize),后端查詢出當頁的數據返回,前端只負責渲染。

特點是:復雜一些;性能瓶頸在MySQL的查詢性能,這個當然可以調優解決。一般來說,web開發使用的是這種方式。

我們說的也是后端分頁。

MySQL對分頁的支持

簡單來說MySQL對分頁的支持是通過limit子句。請看下面的例子。

limit關鍵字的用法是

LIMIT [offset,] rows

offset是相對于首行的偏移量(首行是0),rows是返回條數。

# 每頁10條記錄,取第一頁,返回的是前10條記錄select * from tableA limit 0,10;# 每頁10條記錄,取第二頁,返回的是第11條記錄,到第20條記錄,select * from tableA limit 10,10;

這里提一嘴的是,MySQL在處理分頁的時候是這樣的:

limit 1000,10 - 過濾出1010條數據,然后丟棄前1000條,保留10條。當偏移量大的時候,性能會有所下降。

limit 100000,10 - 會過濾10w+10條數據,然后丟棄前10w條。如果在分頁中發現了性能問題,可以根據這個思路調優。

Mybatis分頁插件PageHelper

在使用Java Spring開發的時候,Mybatis算是對數據庫操作的利器了。不過在處理分頁的時候,Mybatis并沒有什么特別的方法,一般需要自己去寫limit子句實現,成本較高。好在有個PageHelper插件。

1、POM依賴

Mybatis的配置就不多提了。PageHelper的依賴如下。需要新的版本可以去maven上自行選擇

<dependency>      <groupId>com.github.pagehelper</groupId>      <artifactId>pagehelper</artifactId>      <version>4.1.4</version>    </dependency>

2、Mybatis對PageHelper的配置

打開Mybatis配置文件,一般在Resource路徑下。我這里叫mybatis-config.xml。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 全局參數 --><settings>  <!-- 使全局的映射器啟用或禁用緩存。 -->  <setting name="cacheEnabled" value="true"/>  <!-- 全局啟用或禁用延遲加載。當禁用時,所有關聯對象都會即時加載。 -->  <setting name="lazyLoadingEnabled" value="true"/>  <!-- 當啟用時,有延遲加載屬性的對象在被調用時將會完全加載任意屬性。否則,每種屬性將會按需要加載。 -->  <setting name="aggressiveLazyLoading" value="true"/>  <!-- 是否允許單條sql 返回多個數據集 (取決于驅動的兼容性) default:true -->  <setting name="multipleResultSetsEnabled" value="true"/>  <!-- 是否可以使用列的別名 (取決于驅動的兼容性) default:true -->  <setting name="useColumnLabel" value="true"/>  <!-- 允許JDBC 生成主鍵。需要驅動器支持。如果設為了true,這個設置將強制使用被生成的主鍵,有一些驅動器不兼容不過仍然可以執行。 default:false -->  <setting name="useGeneratedKeys" value="true"/>  <!-- 指定 MyBatis 如何自動映射 數據基表的列 NONE:不隱射 PARTIAL:部分 FULL:全部 -->  <setting name="autoMappingBehavior" value="PARTIAL"/>  <!-- 這是默認的執行類型 (SIMPLE: 簡單; REUSE: 執行器可能重復使用prepared statements語句;BATCH: 執行器可以重復執行語句和批量更新) -->  <setting name="defaultExecutorType" value="SIMPLE"/>  <!-- 使用駝峰命名法轉換字段。 -->  <setting name="mapUnderscoreToCamelCase" value="true"/>  <!-- 設置本地緩存范圍 session:就會有數據的共享 statement:語句范圍 (這樣就不會有數據的共享 ) defalut:session -->  <setting name="localCacheScope" value="SESSION"/>  <!-- 設置但JDBC類型為空時,某些驅動程序 要指定值,default:OTHER,插入空值時不需要指定類型 -->  <setting name="jdbcTypeForNull" value="NULL"/></settings><plugins>  <plugin interceptor="com.github.pagehelper.PageHelper">    <property name="dialect" value="mysql"/>    <property name="offsetAsPageNum" value="false"/>    <property name="rowBoundsWithCount" value="false"/>    <property name="pageSizeZero" value="true"/>    <property name="reasonable" value="false"/>    <property name="supportMethodsArguments" value="false"/>    <property name="returnPageInfo" value="none"/>  </plugin></plugins></configuration>  

這里要注意的是PageHelper相關的配置。

如果你沒有加載Mybatis配置文件,那么使用的是Mybatis默認的配置。如何加載Mybatis配置文件呢?

到你的dataSrouce配置中。

在配置sqlSessionFactory的時候,指定Mybatis核心配置文件和mapper的路徑,代碼如下

@Bean(name = "moonlightSqlSessionFactory")  @Primary  public SqlSessionFactory moonlightSqlSessionFactory(@Qualifier("moonlightData") DataSource dataSource) throws Exception {    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();    bean.setDataSource(dataSource);    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis-mapper/*.xml"));    bean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));    return bean.getObject();  }  

 說明:

這里配置的mapper.xml存放路徑,在Resource/mybatis-mapper文件夾下

這里配置的mybatis-config.xml文件,在Resource/下

3、分頁

準備一個mapper.xml,測試就隨便寫一個吧,干脆就用工程里的一個。

這里這個查詢,是一個典型的多條件查詢,我們要做的是對多條件匹配到的記錄進行分頁。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.kangaroo.studio.moonlight.dao.mapper.MoonlightMapper"> <resultMap id="geoFenceList" type="com.kangaroo.studio.moonlight.dao.model.GeoFence">  <constructor>   <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />   <arg column="name" javaType="java.lang.String" jdbcType="VARCHAR" />   <arg column="type" javaType="java.lang.Integer" jdbcType="INTEGER" />   <arg column="group" javaType="java.lang.String" jdbcType="VARCHAR" />   <arg column="geo" javaType="java.lang.String" jdbcType="VARCHAR" />   <arg column="createTime" javaType="java.lang.String" jdbcType="VARCHAR" />   <arg column="updateTime" javaType="java.lang.String" jdbcType="VARCHAR" />  </constructor> </resultMap> <sql id="base_column">id, name, type, `group`, geo, createTime, updateTime </sql> <select id="queryGeoFence" parameterType="com.kangaroo.studio.moonlight.dao.model.GeoFenceQueryParam" resultMap="geoFenceList">  select <include refid="base_column"/> from geoFence where 1=1  <if test="type != null">   and type = #{type}  </if>  <if test="name != null">   and name like concat('%', #{name},'%')  </if>  <if test="group != null">   and `group` like concat('%', #{group},'%')  </if>  <if test="startTime != null">   and createTime >= #{startTime}  </if>  <if test="endTime != null">   and createTime <= #{endTime}  </if> </select></mapper>

在Mapper.java接口中編寫對應的方法

List<GeoFence> queryGeoFence(GeoFenceQueryParam geoFenceQueryParam);

先上分頁代碼,后面再說明      

@RequestMapping(value = "/fence/query", method = RequestMethod.POST)  @ResponseBody  public Response queryFence(@RequestBody GeoFenceQueryParam geoFenceQueryParam) {    try {      Integer pageNum = geoFenceQueryParam.getPageNum()!=null?geoFenceQueryParam.getPageNum():1;      Integer pageSize = geoFenceQueryParam.getPageSize()!=null?geoFenceQueryParam.getPageSize():10;      PageHelper.startPage(pageNum, pageSize);      List<GeoFence> list = moonlightMapper.queryGeoFence(geoFenceQueryParam);      return new Response(ResultCode.SUCCESS, "查詢geoFence成功", list);    } catch (Exception e) {      logger.error("查詢geoFence失敗", e);      return new Response(ResultCode.EXCEPTION, "查詢geoFence失敗", null);    }  }

說明:

1、PageHelper的優點是,分頁和Mapper.xml完全解耦。實現方式是以插件的形式,對Mybatis執行的流程進行了強化,添加了總數count和limit查詢。屬于物理分頁。

2、有一個安全性問題,需要注意一下,不然可能導致分頁錯亂。我這里直接粘貼了這篇博客里的一段話。

4. 什么時候會導致不安全的分頁?

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

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

如果代碼在進入 Executor 前發生異常,就會導致線程不可用,這屬于人為的 Bug(例如接口方法和 XML 中的不匹配,導致找不到 MappedStatement 時), 這種情況由于線程不可用,也不會導致 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>();}

這么寫很不好看,而且沒有必要。

總結

以上所述是小編給大家介紹的Mybatis分頁插件PageHelper的配置和簡單使用方法(推薦),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品成人在线视频| 成人av番号网| 国产主播欧美精品| 亚洲已满18点击进入在线看片| 日韩av免费在线播放| 久久久国产影院| 亚洲视频在线观看| 人体精品一二三区| 欧美日韩在线免费观看| 国产欧美精品一区二区三区介绍| 欧美日本啪啪无遮挡网站| 久久久久久av| 日韩免费看的电影电视剧大全| 亚洲美女在线视频| 国产一级揄自揄精品视频| 色噜噜狠狠色综合网图区| 欧美成人精品不卡视频在线观看| 亚洲福利小视频| 国产精品黄色影片导航在线观看| 91精品国产99久久久久久| 欧美疯狂性受xxxxx另类| 国产精品久久久久久一区二区| 日本视频久久久| 久久久久久高潮国产精品视| 一区二区三区亚洲| 日韩av在线影视| 亚洲国产精品久久久久| 91亚洲国产成人久久精品网站| 日韩在线免费视频| 亚洲第一精品福利| 在线精品视频视频中文字幕| 色悠悠国产精品| 精品久久久久久国产| 日韩欧美国产黄色| 午夜精品美女自拍福到在线| 亚洲色图校园春色| 久久在线免费视频| 欧美理论片在线观看| 亚洲bt欧美bt日本bt| 欧美大尺度电影在线观看| 国产亚洲免费的视频看| 国产亚洲人成a一在线v站| 4438全国成人免费| 亚洲欧洲在线观看| 日本久久久a级免费| 亚洲欧美日韩天堂一区二区| 国产成人在线播放| 国产精品男人爽免费视频1| 91成人性视频| 欧美性在线视频| 国产欧美一区二区三区四区| 久久久999精品| 欧美疯狂xxxx大交乱88av| 国产精品夫妻激情| 亚洲一区二区三区视频播放| 久久99久久99精品中文字幕| 久久久国产精品免费| 欧美日韩成人在线播放| 亚洲国产精品悠悠久久琪琪| 91在线视频九色| 91中文在线视频| 91po在线观看91精品国产性色| 精品一区二区三区四区在线| 欧美成人午夜影院| 91精品国产自产在线| 欧美激情手机在线视频| 日韩电影免费观看中文字幕| 国产日韩精品一区二区| 国产第一区电影| 国产精品旅馆在线| 色av中文字幕一区| 国产一级揄自揄精品视频| 欧美日本高清视频| 国产精品视频男人的天堂| 欧美一级视频免费在线观看| 秋霞成人午夜鲁丝一区二区三区| 91亚洲国产精品| 在线播放日韩av| 欧美成人亚洲成人日韩成人| 日韩小视频网址| 亚洲国产精彩中文乱码av| 高清欧美电影在线| 日韩欧美中文字幕在线播放| 中文字幕成人在线| 国产日韩精品在线| 欧美日韩国产精品一区二区不卡中文| 国产精品成人免费视频| 国产97在线|亚洲| 精品国产网站地址| 亚洲丁香婷深爱综合| 国内精品模特av私拍在线观看| 国产精品一二三在线| 国产一区二区三区久久精品| 日产精品99久久久久久| 色爱av美腿丝袜综合粉嫩av| 国产精品视频白浆免费视频| 精品久久久久久久久久久久久| 日韩精品999| 国产91精品不卡视频| 国产精品久久久亚洲| 欧美疯狂性受xxxxx另类| 91久久夜色精品国产网站| 亚洲欧美在线一区二区| 国产精品人人做人人爽| 欧美性资源免费| 精品久久久久久久久久久久久| 欧美午夜片在线免费观看| 亚洲欧美国产一本综合首页| 日韩美女免费线视频| 日韩精品在线免费| 日韩资源在线观看| 日韩av免费在线| 亚洲免费视频网站| 久久视频国产精品免费视频在线| 欧美激情亚洲自拍| 国产精品永久免费在线| 国产精品视频一区二区三区四| 91tv亚洲精品香蕉国产一区7ujn| 成人福利在线视频| 亚洲欧美精品一区| 97国产suv精品一区二区62| 精品一区二区三区电影| 日韩精品视频在线观看免费| 国产精品日韩在线观看| 91国产美女在线观看| 欧美性理论片在线观看片免费| 国产成人精品免高潮费视频| 欧美大片在线看免费观看| 亚洲精品福利资源站| 亚洲娇小xxxx欧美娇小| 欧美在线国产精品| 欧美国产日韩精品| 啪一啪鲁一鲁2019在线视频| 久久艹在线视频| 亚洲男人天堂古典| 欧美乱大交xxxxx另类电影| 在线精品视频视频中文字幕| 91久久在线观看| 欧美国产日韩中文字幕在线| 久久精品91久久久久久再现| 丝袜美腿亚洲一区二区| 国产精品久久国产精品99gif| 成人国产精品日本在线| 国产亚洲成精品久久| 少妇高潮久久77777| 国产日韩av在线| 日韩精品免费在线视频观看| 欧美一乱一性一交一视频| 国产精品一区二区久久国产| 久久久久久久久91| 国产日韩欧美成人| 亚洲丁香久久久| 孩xxxx性bbbb欧美| 精品偷拍各种wc美女嘘嘘| 国产精品永久在线| 国外日韩电影在线观看| 色偷偷91综合久久噜噜| 国模叶桐国产精品一区| 日韩精品中文字幕视频在线| 亚洲成人激情小说| 最近日韩中文字幕中文| 国产91热爆ts人妖在线| 欧美性jizz18性欧美| 亚洲第一视频在线观看|