注:このブログは現在のページングプラグインとはまったく異なるため、上記のプロジェクトアドレスを介して最新のソースコードとドキュメントを確認して理解することをお勧めします。
私は以前にMybatis Paginationのクエリを心配していましたが、オンラインで多くの関連記事を検索しましたが、最後の記事は使用しませんでした。ページングの場所は、SQLとカウントSQLで完全に手書きされています。これは非常に面倒です。
後で、しばらくの間、私はMybatis内からページネーションの実装を書きたかったのです。私は言語装置の実装を書きました。自動ページネーションには問題はありませんが、クエリの総数(カウント)は一度に解決することはできず、未解決のままでした。
最近、私は再びページネーションを使用する必要があります。便利なため、一般的なページネーションクラスを書く必要があるため、インターネット上のほとんどのMyBatisページネーションコードを再び参照します。
実際、昔、誰かがGitHubでソース実装を開き、MySQL、Oracle、およびSQLServerをサポートしました。しかし、あまりにも多くのクラスが面倒すぎると思うので、1つのインターセプターのみでクラスを実装しました。実際には2つのクラスに分けることができます。クラスの1つは、私によって静的クラスとして書かれ、インターセプターに配置されました。ページクラスを抽出して、ページの使用を容易にすることもできます。
最初に実装方法について話しましょう。このプラグインには、PageHelper.javaのクラスが1つしかありません
インターセプターの署名は次のとおりです。
@intercepts({ @signature(type = statementhandler.class、method = "prepare"、args = {connection.class})、 @signature(type = resterethandler.class、method = "handleresultsets"、args = {statement.class})}))ここでの署名は、実装とアイデア全体に不可欠です。最初に、ページネーションSQLを変更してカウントクエリを変更するための準備方法を傍受します。次に、Handleresultsetsメソッドをインターセプトして最後の処理結果を取得し、結果をページオブジェクトに入れます。
以下は、Oracleデータの変更であるページを変更するためのコードです。他のデータベースを使用する場合、ここでコードを自分で変更できます。
/ ** *元のSQLをページネーションSQLに変更しますpagesql.append( "select * from(select temp。 *、rownum row_id from("); pagesql.append(sql); pagesql.append( ")temp where rownum <=").getendrow(); pagesql.append( ")where row_id>")。 pagesql.toString()を返します。 }
次に、次のSetPageParameterメソッドでは、データベースタイプに従って選択するカウントステートメントを変更する必要があります。
//レコードの総数string countsql = "(" + sql + ")" from( " + sql +") "from select(0);
さまざまなデータベースをサポートしないのはなぜですか?必要ではないと思います。一部のデータベースはページングをサポートしておらず、このプラグインがより簡単になるほど、開発者が理解して変更するのが簡単です。必要なページネーションクエリに変更することは、間違いなく問題ではありません。
最後に、完全なコードが追加されます(読み続け、以下に使用方法もあります):(クリックしてダウンロード)
パッケージcom.mybatis.util; org.apache.ibatis.executor.parameter.parameterhandlerをインポートします。 org.apache.ibatis.executor.resultset.resultsethandlerをインポートします。 org.apache.ibatis.executor.statement.statementhandlerをインポートします。 Import org.apache.ibatis.mapping.boundsql; Import org.apache.ibatis.mapping.mappedStatement; org.apache.ibatis.plugin。*; org.apache.ibatis.reflection.metaobjectをインポートします。 org.apache.ibatis.reflection.systemmetaobjectをインポートします。 org.apache.ibatis.scripting.defaults.defaultparameterhandlerをインポートします。 org.apache.log4j.loggerをインポートします。 Java.sql。*をインポートします。 java.util.listをインポートします。 java.util.propertiesをインポートします。 /*** mybatis-Universal Pagination Interceptor* @author liuzh/abel533/isea* 14-4-15にLiuzhによって作成されました。 */ @intercepts({ @signature(type = statementhandler.class、method = "prepare"、args = {connection.class})、 @signature(type = resterethandler.class、method = "handleresultsets"、args = {statement.class})})public class pagehelperter = prive static static greger gren logger.getLogger(pagehelper.class); public static final threadlocal <page> localpage = new threadlocal <page>(); / ** * Pagingを開始 * @param pagenum * @param pagesize */ public static void startpage(int pagenum、int pagesize){localpage.set(new page(pagenum、pagesize)); } /***ページングを終了し、結果を返します。メソッドを呼び出す必要があります。そうしないと、次のstartpage * @return */ public staticページendpage(){page page = localpage.get(); localpage.remove();返信ページ。 } @Override public Object intercept(Invocation Invocation)Throws Throws {if(localpage.get()== null){return invocation.proceed(); } if(invocation.getTarget()Instanceof StatementHandler){StatementHandler StatementHandler =(StatementHandler)Invocation.GetTarget(); MetaObject MetastatementHandler = SystemMetaObject.ForObject(StatementHandler); //プロキシオブジェクトチェーンを分離します(ターゲットクラスが複数のインターセプターによって傍受される可能性があるため、複数のプロキシが形成され、次の2つのループが形成されます//最も原始的なターゲットクラスを分離できます)while(Metastatementhandler.hasgetter( "h")){object object = metastatementementhandler.getvalue( "h"); MetastatementHandler = SystemMetaObject.ForObject(object); } //最後のプロキシオブジェクトを分離するターゲットクラス(metastatementhandler.hasgetter( "target")){object object = metastatementhandler.getValue( "ターゲット"); MetastatementHandler = SystemMetaObject.ForObject(object); } mappedStatement mappedStatement =(mappedStatement)metastatementhandler.getValue( "Delegate.Mapptatement"); //ページ情報if(localpage.get()!= null){page page = localpage.get(); Boundsql Bundsql =(BundsQl)MetastatementHandler.getValue( "Delegate.BoundSQL"); // parameterObjectパラメーターとしてのページパラメーターパラメーターパラメーターSql = BundSQL.GetSQL(); // sql文字列pagesql = buildpagesql(sql、page); //ページングSQL MetastateMentHandler.SetValue( "Delegate.BoundSQL.SQL"、PagesQL);接続接続=(connection)rikocation.getargs()[0]; //ページングパラメーターなどのページの総数をリセットします。SetPageParameter(SQL、Connection、MappedStatement、BoundSQL、Page); //次のインターセプターへの実行権を渡しますreturn return rick.proceed(); } else if(rivocation.getTarget()instanceof resultsethandler){object result = vimocation.proceed();ページページ= localpage.get(); page.setResult((list)result);返品結果; } nullを返します。 } / ** *これらの2つのタイプの * StatementHandler * resthandler * @param Target * @return * / @Override Public Objectプラグイン(オブジェクトターゲット){if(Target InstanceOf StatementHandler || runter plugin.wrap(ターゲット、this); } else {return target; }} @Override public void setProperties(プロパティプロパティ){} / ** *元のSQLをページネーションSQLに変更します * @Param SQL * @param Page * @return * / private string buildpagesql(String SQL、Pageページ){StringBuilder PagesQL = New StringBuilder(200); pagesql.append( "select * from(select temp。 *、rownum row_id from("); pagesql.append(sql); pagesql.append( ")temp where rownum <=").getendrow(); pagesql.append( ")where row_id>")。 pagesql.toString()を返します。 } / ** *レコードの総数を取得 * @param sql * @param connection * @param mappedstatement * @param boundsql * @param page * / private void setPageParameter(String SQL、Connection Connection、MappedStatement MappedStatement、Boundsql Boundsql、Page) sql + ")"; preatedStatement countStmt = null;結果rs = null; try {countstmt = connection.preparestatement(countSQL); Boundsql countbs = new BoundSql(MappedStatement.GetConfiguration()、CountSQL、BundsQl.GetParameterMappings()、Bundsql.getParameterObject()); setParameters(countStmt、MappedStatement、countbs、Boundsql.getParameterObject()); rs = countstmt.executequery(); int totalcount = 0; if(rs.next()){totalcount = rs.getint(1); } page.settotal(totalcount); int totalpage = totalcount / page.getPagesize() +((totalcount%page.getPagesize()== 0)?0:1); page.setPages(TotalPage); } catch(sqlexception e){logger.error( "この例外を無視する"、e); }最後に{try {rs.close(); } catch(sqlexception e){logger.error( "この例外を無視する"、e); } try {countstmt.close(); } catch(sqlexception e){logger.error( "この例外を無視する"、e); }}} / ** *代替パラメーター値 * @param ps * @param mappedstatement * @param boundsql * @param parameterobject * @throws sqlecception * / private void setparameters(predapedStatement PS、mappedstatement mappedstatement、boundsql、boundsql、Object parameter parmeter)parameter DefaultParameterHandler(MappedStatement、ParameterObject、BundSQL); parameterHandler.setParameters(PS); } / ** *説明:ページネーション *著者:liuzh *更新:liuzh(2014-04-16 10:56) * / public static classページ<e> {private int pagenum; Private int Pagesize; Private int Startrow; Private int Endrow;プライベートロング合計;プライベートINTページ。プライベートリスト<e>結果;パブリックページ(int pagenum、int pagesize){this.pagenum = pagenum; this.pagesize = pagesize; this.startrow = pagenum> 0? (Pagenum -1) * Pagesize:0; this.endrow = pagenum * pagesize; } public list <e> getResult(){return result; } public void setResult(list <e> result){this.result = result; } public int getPages(){return Pages; } public void setPages(int pages){this.pages = pages; } public int getEndrow(){return endrow; } public void setendrow(int endrow){this.endrow = endrow; } public int getPagenum(){pagenumを返します。 } public void setPagenum(int pagenum){this.pagenum = pagenum; } public int getPagesize(){return pagesize; } public void setPagesize(int pagesize){this.pagesize = pagesize; } public int getstartrow(){return startrow; } public void setstartrow(int startrow){this.startrow = startrow; } public long gettotal(){return total; } public void settotal(長い合計){this.total =合計; } @Override public String toString(){return "page {" + "pagenum =" + pagenum + "、pagesize =" + pagesize + "、startrow =" + startrow + "、endrow =" + endrow + "、total =" + total + "、pages =" + pages + '}'; }}}このインターセプターを使用するには、最初にMyBatis構成でインターセプターを構成する必要があります。
<プラグイン> <プラグインInterceptor = "com.mybatis.util.pagehelper"> </plugin> </plugins>
インターセプターを構成するときは、プラグインの場所に注意を払う必要があります。プラグインの順序は次のとおりです。
プロパティ?、設定?、TypeAliase?、TypeHandlers?、ObjectFactory?、ObjectWrapperFactory?、プラグイン?、環境?、データベースIdprovider?、Mappers?
最後に、この方法を呼び出す例コード(サービスレイヤー)があります。
@Override public pagehelper.page <sysloginlog> findsysloginlog(string loginip、string username、string logindate、string logerr、int pageNumber、int pagesize)slows businessexception {pagehelper.startpage(pagenumber、pageNumber、pageNumber); sysloginlogmapper.findsysloginlog(loginip、username、logindate、exitdate、logerr); return pagehelper.endpage(); }上記から、このプラグインを使用することは非常に簡単であることがわかります。クエリの前後にPageHelperのStartPageおよびEndPageメソッドを使用する必要があります。中間コードの呼び出し結果は、PageHelperの結果にすでに存在します。結果を返す場所でPageHelperを呼び出すと、返された結果はまだリストです。最初の値を取ることができます(この場所では誰もこのように使用しないと思います。もちろん、このようにエラーはありません)。
さらに、StartPageとEndPageの間のすべてのMyBatisコードがパジネートされ、PageHelperは最後の結果のみを保持します。したがって、それを使用する場合、一度に1つのMyBatisクエリのみが実行されるようにする必要があります。複数のページングがある場合は、StartPageとEndPageを複数回使用してください。
ここではOracleの実装のみが提供されるため、このページングプラグインによって実装された他のデータベースを参照する読者が対応するコードをオープンソースにできることを願っています。
プロジェクトアドレス:http://xiazai.vevb.com/201612/yuanma/mybatis_pagehelper_jb51.zip
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。