序文
テーブルがDatatableなどのWeb開発に関与すると、ページングの必要性が生じます。通常、ページング方法をフロントエンドのページングとバックエンドページングの2つのタイプに分けます。
フロントエンドページネーション
データテーブル内のすべてのレコード(AJAX)が一度に要求され、その後、フロントエンドでキャッシュされ、カウントとページングロジックを計算します。一般的に、フロントエンドコンポーネント(Datatableなど)はページングアクションを提供します。
機能は次のとおりです。シンプルで、小規模なWebプラットフォームに非常に適しています。データの量が多いときにパフォーマンスの問題が発生し、クエリとネットワーク伝送の時間が長くなります。
バックエンドページネーション
Ajaxリクエストでページ番号(Pagenum)と各ページのサイズ(Paysize)を指定します。バックエンドはページのデータを照会して返し、フロントエンドはレンダリングのみを担当します。
機能は次のとおりです。パフォーマンスボトルネックはMySQLのクエリパフォーマンスにあり、もちろん最適化および解決できます。一般的に、Web開発ではこの方法を使用しています。
バックエンドページネーションについて話している。
ページネーションのMySQLサポート
簡単に言えば、MySQLはLimit句を介したページネーションをサポートします。以下の例をご覧ください。
Limitキーワードの使用法はです
[オフセット]を制限します
オフセットは、最初の行に対するオフセット(最初の行は0)、行は行数です。
#各ページには10のレコードがあり、最初のページを取り、最初の10レコードを返しますselect * tablea limit 0,10;#各ページには10のレコードがあり、2番目のページを取り、11番目のレコードを20番目のレコードに戻します。
ここで言及したいのは、mysqlがページネーションを処理するときです。
1000,10を制限 - 1010個のデータを除外してから、最初の1000個を破棄し、10個を保持します。オフセットが大きいとパフォーマンスが低下します。
100000,10を制限 - 10W+10個のデータをフィルタリングし、最初の10Wピースを破棄します。ページネーションでパフォーマンスの問題が見つかった場合、このアイデアに従ってそれらを調整できます。
MyBatisページングプラグインPageHelper
Java Spring開発を使用する場合、MyBatisはデータベース操作のための強力なツールです。ただし、ページングに対処する場合、MyBatisには特別な方法はありません。一般的に、それを実装するために自分で制限条項を書く必要がありますが、これは比較的高価です。幸いなことに、PageHelperプラグインがあります。
1。POM依存関係
MyBatisの構成については言及しません。 PageHelperの依存関係は次のとおりです。新しいバージョンが必要な場合は、Mavenで選択できます
<Dependency> groupId> com.github.pagehelper </groupid> <artifactid> pagehelper </artifactid> <バージョン> 4.1.4 </version> </dependency>
2。PageHelperのMyBatis構成
通常、リソースパスの下でMyBatis構成ファイルを開きます。私の名前はmybatis-config.xmlです。
<?xml version = "1.0" encoding = "utf-8"?> <!doctype構成public " - // mybatis.org//dtd config 3.0 // en" "http://mybatis.org/dtd/mybatis-3-config.dtd"またはキャッシュを無効にします。 - > <name = "cacheenabled" value = "true"/> <! - 怠zyなロードをグローバルに有効または無効にします。無効にすると、関連するすべてのオブジェクトが即座にロードされます。 - > <name = "lazyloadingEnabled" value = "true"/> <! - 有効にすると、怠zyなロードプロパティを持つオブジェクトは、呼び出されたときに任意のプロパティを完全にロードします。それ以外の場合、各プロパティは必要に応じてロードされます。 - > <name = "aggressivelazyloading" value = "true"/> <! - 単一のSQLが複数のデータセットを返すことを許可するかどうか(ドライバーの互換性に応じて)デフォルト:true-> <name = "multipleresultsetsenabled" value = "true"/> < name = "usecolumnlabel" value = "true"/> <! - jdbcがプライマリキーを生成することを許可します。ドライブサポートが必要です。 Trueに設定されている場合、この設定は生成されたプライマリキーを強制します。一部のドライブは互換性がありませんが、実行できます。デフォルト:false - > <name = "usegeneratedkeys" value = "true"/> <! - mybatisがデータベースのテーブルの列を自動的にマッピングする方法を指定します。ステートメントとバッチの更新) - > <name = "defaultexecutortype" value = "simple"/> <! - キャメル命名法を使用してフィールドを変換します。 - > <name = "Mapunderscoretocamelcase" value = "true"/> <! - ローカルキャッシュ範囲セッションの設定:データ共有ステートメントがあります。ステートメントスコープ(これはデータ共有ではありません)defalut:> <name = "localcachescope" value = "session"/> <! null値を挿入する場合 - > <name = "jdbctypefornull" value = "null"/> </settings> <plugin interceptor = "com.github.pagehelper.pagehelper"> <プロパティ名= "value =" mysql "/> <property =" fall "/>"> "offscapsaspagenum"/> value = "false"/> <プロパティ名= "pagesizezero" value = "true"/> <property name = "妥当な" value = "false"/> <property name = "supportmethodsarguments" value = "false"/> <property name = "returnpageinfo" value = "none"/> </blugin> </</confyuation> <
ここに注意する必要があるのは、PageHelperに関連する構成です。
MyBatis構成ファイルをロードしない場合は、MyBatisデフォルト構成を使用しています。 MyBatis構成ファイルをロードする方法は?
DataSrouce構成に移動します。
sqlsessionFactoryを構成する場合、MyBatisコア構成ファイルとマッパーパスを指定すると、コードは次のとおりです。
@bean(name = "moonlightsqlsessionfactory")@primary public sqlsessionfactory voonlightsqlsessionfactory( @qualifier( "moonlightdata")datasource datasource)スロー例外{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ストレージパスはリソース/mybatis-mapperフォルダーにあります
ここで構成されているmybatis-config.xmlファイルはリソースの下にあります/
3。ページネーション
mapper.xmlを準備し、テスト用に1つ書き、プロジェクトの1つだけを使用してください。
ここでのこのクエリは、典型的なマルチコンディションクエリです。私たちがしなければならないことは、複数の条件に合ったレコードをページングすることです。
<?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"> <construction> <idarg = "id" javatype = "java.inte" jdbctype = "integer" /> <arg column = "name" javatype = "java.lang.string" jdbctype = "varchar" /> <arg column = "type" javatype = "java.lang.integer" jdbctype = "integer" /> <arg "javatype" javatype "javatype" javatype " jdbctype = "varchar" /> <arg column = "geo" javatype = "java.lang.string" jdbctype = "varchar" /> <arg column = "createTime" javatype = "java.lang.string" jdbctype = "varchar" />> <arg "javatype jdbctype = "varchar"/> </constructor> </resultmap> <sql id = "base_column"> id、name、type、 `group`、geo、createTime、updateTime </sql> resultmap = "geofenceList"> select <include refid = "base_column"/> from geofence from geofence from 1 = 1 <if test = "type!= null">およびtype =#{type} </if> <if> "name"> concat( '%'、 '%'、#{name}、 '%')< concat( '%'、#{group}、 '%')</if> <if> <if test = "starttime!= null">およびcreateTime> =#{starttime} </if> <if> <if> "endtime!= null"> and createTime <=#{endtime} </if> </select> </select> </select> </select> </select> </Mapper.javaインターフェイスに対応するメソッドを書きます
リスト<Geofence> QueryGeOfence(GeofenceQueryParam GeofenceQueryParam);
まず、ページコードを追加してから後で説明します
@RequestMapping(value = "/fence/query"、method = requestmethod.post)@responsebody public respons queryfence(@requestbody geofencequeryparam geofencequeryparam){try {integer pagenum = geofencequeryparam.getpagenum()!= null? integer pagesize = geofencequeryparam.getPagesize()!= null?geofencequeryparam.getPagesize():10; pagehelper.startpage(pagenum、pagesize);リスト<Geofence> list = moonlightmapper.querygeofence(geofencequeryparam);新しい応答を返します(resultCode.success、 "query geofence success"、list); } catch(Exception e){logger.error( "Query Geofence Failed"、e);新しい応答を返します(resultCode.Exception、 "query geofence failed"、null); }}説明:
1. PageHelperの利点は、PaginationとMapper.xmlが完全に分離されていることです。実装方法は、プラグインの形でMyBatis実行プロセスを強化し、合計カウントと制限クエリを追加することです。物理ページに属します。
2。注意を払う必要があるセキュリティの問題があります。そうしないと、ページング障害につながる可能性があります。私はここでこのブログから直接通路を貼り付けました。
4。それはいつ危険なページングにつながりますか?
PageHelperメソッドは静的Threadlocalパラメーターを使用し、ページングパラメーターとスレッドがバインドされています。
PageHelperメソッドがすぐにMyBatisクエリメソッドが続くと呼ばれることを確認できる限り、これは安全です。 PageHelperが最終的にスニペットに糸状局所保存されたオブジェクトを自動的にクリアするためです。
執行者に入る前に例外が発生した場合、スレッドは利用できません。これは人間のバグです(インターフェイスメソッドとXMLの間の不一致など、マッピングステートメントが見つかりません)。この状況では、スレッドが利用できないため、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(); }最後に{pagehelper.clearpage(); }} else {list = new arraylist <country>();}このように書くのは良くありませんし、必要ではありません。
要約します
上記は、編集者が紹介したMyBatis Paging Plugin PagyHelperの構成と簡単な使用方法(推奨)です。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!