次のページのアイデアによると、MyBitasのマルチテナントデザインを簡単に実装できます。
MyBatisが提供するインターセプターを使用します。ページングされたSQLステートメントは、カプセル化を介して異なるページングSQLに処理されます。
この例は、MySQLとOracleのページネーション関数を実装しています。次の引用パッケージに注意してください。誤って引用しないでください。
java.sql.connection; Import java.sql.preparedStatement; Import java.sql.Resultset; Import java.sql.sqlecception; Import java.util.list; Import java.util.properties; import org.apache.ibatis. apache.ibatis.executor.statement.routingstatementhandler; import org.apache.ibatis.executor.statement.statementhandler; Import org.apache.ibatis.mapping.boundsql; Import org.apache.ibatis.mapping.mapptatementmentmentmentmentmentmentement; org.apache.ibatis.plugin.interceptor; Import org.apache.ibatis.plugin.intercepts; Import org.apache.ibatis.plugin.invocation; import org.apache.ibatis.plugin; plugin; import org.apache.ibatis.plugin.signature; import; org.apache.ibatis.scripting.defaults.defaultparameterhandler; Import com.yidao.utils.page; import com.yidao.utils.refllecthelper;/** * *ページングクエリを必要とする操作を傍受するために使用し、その後ページングを必要とする操作を傍受するために使用されます。 * MyBatisページングの原理は、インターセプターを使用して実装されます。 * JDBCを使用してデータベースを動作させるには、対応するステートメントオブジェクトが必要です。 MyBatisがSQLステートメントを実行する前に、SQLステートメントを含むステートメントオブジェクトを生成し、対応するSQLステートメント*はステートメントの前に生成されるため、ステートメントを生成する前にステートメントを生成するために使用されるSQLステートメントから始めることができます。 MyBatisステートメントでは、RoutingStatementHandlerオブジェクトの *準備方法によって生成されます。したがって、インターセプターを使用してMyBatisページングを実装するためのアイデアの1つは、StatementHandlerインターフェイスの準備方法をインターセプトし、SQLステートメントをインターセプターメソッドの対応するページネーションクエリSQLステートメントに変更し、 * StatementHandlerオブジェクトの準備方法を呼び出すことです。 *ページネーションの場合、インターセプターで行う必要がある操作の1つは、現在の条件を満たすレコードの総数をカウントすることです。これは、元のSQLステートメントを取得し、対応する統計ステートメントに変更し、MyBatisカプセル化されたパラメーターと設定 *パラメーターを使用してSQLステートメントのパラメーターを置き換えることです。次に、レコードの数をクエリするSQLステートメントが実行され、レコードの総数がカウントされます。 * */ @intercepts({ @signature(type = statementhandler.class、method = "prepare"、args = {connection.class})})public class pageinterceptor Interceptor {private string dierect = ""; //データベース方言プライベート文字列pagesqlid = ""; // mapper.xml(通常の一致)で傍受する必要があるID(通常の試合)パブリックオブジェクトインターセプト(呼び出し)スロー可能{//実際にはStatementHandlerの2つの実装クラスのみがあります。 // BaseStatementHandlerには、SimpleStateMentementHandler、preatedStatementhandler、CallableStatementhandlerの3つのサブクラスがあります。 // SimpleStatementHandlerは、ステートメントの処理に使用され、準備されたステートメントラーハンドルrepedStatement、およびcallablestatementhandlerは// processes callablestatementです。 MyBatisは、SQLステートメントを処理するときにRoutingStatementHandlerを作成します。 RoutingStatementHandlerには、// StatementHandler Typeのデリゲートプロパティがあります。 RoutingStatementHandlerは、さまざまなステートメント、つまりSimplestatementHandler、// preatedstatementhandlerまたはcallablestatementhandlerに従って、対応するBasestatementhandlerを作成します。 RoutingStatementHandlerでは、すべてのStatementHandlerインターフェイスメソッドが、呼び出された代表者に対応する代表者によって実装されます。 //インターセプターは、PageInterceptorクラスの@SignatureとStatementHandlerインターフェイスの準備方法のみをインターセプトすることのみをマークしました。 MyBatisは、RoutingStatementementHandlerを確立するときにインターセプタープラグインメソッドを介してそれを包むため、ここでインターセプトするターゲットオブジェクトはRoutingStatementhandlerオブジェクトでなければなりません。 if(Invocation.getTarget()Instanceof routingStatementHandler){routingStatementHandler StatementHandler =(routingStatementHandler)rivocation.getTarget(); StatementHandler Delegate =(StatementHandler)ReflectHelper.getFieldValue(StatementHandler、 "Delegate"); Boundsql Bundsql = Delegate.GetBoundSQL();オブジェクトobj = boundsql.getParameterObject(); if(obj instanceof page <?>){page <?> page =(page <? //デリゲートの親クラスのベース測定ハンドラーのマッピングステートメントプロパティを取得マッピングステートメント=(MappedStatement)refrectHelper.getFieldValue(Delegate、 "MappedStatement"); //インターセプトされた準備メソッドのパラメーターは、接続オブジェクト接続=(接続)招き.getargs()[0]; //現在実行されているsqlステートメント、つまり、マッパーマッピングステートメント文字列sql = bundsql.getsql()で直接記述するsqlステートメントを取得します。 //現在のページパラメーターオブジェクトのレコードの総数を設定します。 // Paged SQLステートメント文字列PagesQl = this.getPagesQl(Page、SQL)を取得します。 //反射を使用して、現在のBoundSQLに対応するSQL属性を設定して、私たちのための適切なページSQLステートメントを作成します。 }} return ichvocation.proceed(); } /***現在のパラメーターオブジェクトのレコードの総数を設定*** @paramページマッパーマッピングステートメント* @param mappedstatementマッピングマッピングステートメント* @param接続現在のデータベース接続* /private void setotalrecord(ページ<?このBoundSQLは、実際にはStatementHandlerを使用して取得したBoundSQLと同じオブジェクトです。 //デリゲートのBoundSQLは、MappedStatement.GetBoundSQL(PARAMOBJ)メソッドによっても取得されます。 Boundsql Bundsql = mappedStatement.getBoundSql(page); //対応するsqlステートメント文字列sql = boundsql.getsql()を取得します。 // SQLステートメント文字列countSQL = this.getCountSQL(SQL)を照会することにより、レコードの総数を計算する対応するSQLステートメントを取得します。 // bundsql list <parametermapping> parametermappings = boundsql.getParametermappings()を介して対応するパラメーターマップを取得します。 //構成、sqlステートメントカウントレコード、パラメーターマッピング関係パラメーターエマッピング、およびパラメーターオブジェクトページを使用して、クエリレコードに対応するBoundSQLオブジェクトを作成します。 BoundsQl countBoundSql = new BoundSQL(MappedStatement.GetConfiguration()、CountSQL、ParameterMappings、Page); // MappedStatement、パラメーターオブジェクトページ、およびBoundSQLオブジェクトCountBoundSQLを使用してパラメーターを設定するパラメーターハンドラーオブジェクトを作成します。 parameterHandler parameterhandler = new DefaultParameterHandler(MappedStatement、Page、CountBoundSQL); //接続を介してCountSQLに対応する準備されたステートメントオブジェクトを作成します。 predtatement pstmt = null;結果rs = null; try {pstmt = connection.preparestatement(countsql); // parameterhandler.setParameters(PSTMT)を介して準備オブジェクトのパラメーターパラメーターハンドラーを設定します。 //次に、レコードの総数を取得し、結果を取得するために実行されます。 rs = pstmt.executequery(); if(rs.next()){int totalRecord = rs.getint(1); //現在のパラメーターページオブジェクトのレコードの総数を設定します。SettotalRecord(TotalRecord); }} catch(sqlexception e){e.printstacktrace(); }最後に{try {if(rs!= null)rs.Close(); if(pstmt!= null)pstmt.close(); } catch(sqlexception e){e.printstacktrace(); }}} / ** * query * @param sql * @return * / private string getcountsql(string sql){int index = sql.indexof( "from"); 「count(*)」 + sql.substring(index)を返します。 } /***ページオブジェクトに基づいて、対応するページネーションクエリSQLステートメントを取得します。ここでは2つのデータベースタイプのみが作成されます。MySQLとOracle *他のデータベースはページングされていません * * @paramページページングオブジェクト * @Param SQL Original SQL Statement * @return */ private String getPagesQl(Page <? if( "mysql" .equalsignorecase(方言)){return getmysqlpagesql(page、sqlbuffer); } else if( "oracle" .equalsignorecase(方言)){return getOraclePagesQl(page、sqlbuffer); } return sqlbuffer.toString(); } / *** mysqlデータベースのページクエリステートメントを取得* @paramページページングオブジェクト* @param sqlbuffer stringbufferオブジェクトオリジナルのsqlステートメント* @return mysql database pagingステートメント* / private string getmysqlpagesql(page <?> singbuffer sqlbuffer sqlbuffer) MySQLのレコードの位置は0から始まります。 int offset =(page.getPage() - 1) * page.getRows(); sqlbuffer.append( "lime").append(offset).append( "、")。append(page.getRows()); return sqlbuffer.toString(); } / *** Oracle Databaseのページクエリステートメントを取得* @paramページページングオブジェクト* @param sqlbuffer stringbufferオブジェクトオリジナルSqlステートメント* @return Pagination queryステートメント* / private string getoraclepagesql(Page <?>ページ、Stringbuffuffer) Oracle PaginationはRownumを通じて実行され、Rownumは1 int offset =(page.getPage() - 1) * page.getRows() + 1から始まります。 sqlbuffer.insert(0、 "select u。*、rownum r from(").append( ")u where rownum <").append(offset + page.getRows()); sqlbuffer.insert(0、 "select * from(").append( ")where r> =").append(offset); //上記のsqlステートメントは次のようになります:// select * from(select u。 *、rownum r from(select * from t_user)u where rownum <31)where r> = 16 return sqlbuffer.toString(); } / ***インターセプターに対応する元のオブジェクトをカプセル化する方法* / public objectプラグイン(Object arg0){// todo auto-eneratedメソッドスタブif(arg0 instanceof statenthandler){return plugin.wrap(arg0、this); } else {return arg0; }} / ***インターセプターを登録するときに設定されたプロパティを設定* / public void setProperties(Properties P){} public String getDialect(){return dierect; } public void setDialect(string dierect){this.dialect = dialect; } public string getPagesQlid(){return pagesqlid; } public void setPagesQlid(string pagesqlid){this.pagesqlid = pagesqlid; }} XML設定:
<! - mybatisインターフェイスプログラミング構成 - > <bean> <! - ベースパッケージスキャンするパッケージを指定します。このパッケージの下のマッパーが検索されます。複数のパッケージを指定して、コンマまたはセミコロンで区切ることができます - > <プロパティ名= "basepackage" value = "com.yidao.mybatis.dao" /> <プロパティ名= "sqlsessionfactorybeanname" value = "sqlsessionfactory" />> < /bean> <! name = "dialect" value = "mysql"/> <! - マッパー.xmlファイルにクエリ文字を含むIDでステートメントを傍受 - > <プロパティname = "pagesqlid" value = "。*query $"/> </bean> </bean> <
ページクラス
パッケージcom.yidao.utils;/**自分で見てください。どのフィールドに追加する必要がありますか*/public classページ{private integer rows;プライベート整数ページ= 1;プライベート整数TotalRecord; public Integer getRows(){return行; } public void setrows(整数行){this.rows = rows; } public Integer getPage(){return Page; } public void setPage(整数ページ){this.page = page; } public Integer getTotalRecord(){return totalRecord; } public void settotalRecord(integer totalRecord){this.TotalRecord = TotalRecord; }} Helperクラスを反映します
パッケージcom.yidao.utils; Import java.lang.Reflect.field; Import org.apache.commons.lang3.Reflt.fieldutils; public class refrecthelper {public static object getFieldValue(オブジェクトobj、文字列フィールド名){if(obj == null){retrent null; } field targetfield = getTargetField(obj.getClass()、FieldName); try {return fieldutils.readfield(Targetfield、obj、true); } catch(Illegalaccessexception e){e.printstacktrace(); } nullを返します。 } public static field gettargetfield(class <?> TargetClass、string fieldName){field field = null; try {if(targetclass == null){return field; } if(object.class.equals(targetclass)){return field; } field = fieldutils.getDeclaredfield(TargetClass、FieldName、True); if(field == null){field = getTargetField(targetClass.getSuperClass()、fieldName); }} catch(例外e){} return field; } public static void setFieldValue(Object obj、string fieldname、object value){if(null == obj){return;} field targetfield = getTargetfield(obj.getClass()、fieldName); try {fieldutils.writefield(Targetfield、obj、value); } catch(Illegalaccessexception e){e.printstacktrace(); }}}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。