Согласно идее следующей страницы, легко реализовать мультитенантный дизайн Mybitas.
Используйте перехватчик, предоставленный Mybatis. Операторы SQL -страницы обрабатываются в различные SQL -SQL с помощью инкапсуляции.
Этот пример реализовал функцию странификации MySQL и Oracle. Обратите внимание на следующий пакет для котировок и не цитируйте его неправильно.
Импорт java.sql.connection; импорт java.sql.preparedStatement; импорт java.sql.resultset; import java.sql.sqlexception; import java.util.list; import java.util.properties; импорт org.apache.ibatis.executor.parameter.parameters; org.apache.ibatis.executor.statement.RoutingStatementHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.ParameterMapping;import org.apache.ibatis.plugin.interceptor; import org.apache.ibatis.plugin.intercepts; import org.apache.ibatis.plugin.invocation; импорт org.apache.ibatis.plugin.plugin; импорт org.apache.ibatis.pluge.signature; импорт. org.apache.ibatis.scripting.defaults.defaultparameterhandler; импорт com.yidao.utils.page; import com.yidao.utils.reflecthelper;/** * * * * * * Принцип Pageging Pagingis реализуется с использованием перехватчиков: * Для использования JDBC для работы в базе данных вы должны иметь соответствующий объект оператора. Прежде чем MyBatis выполнит оператор SQL, он будет генерировать объект оператора, содержащий оператор SQL, и соответствующий оператор SQL* генерируется до оператора, поэтому мы можем начать с оператора SQL, используемого для генерации оператора, прежде чем он генерирует оператор. В операторе Mybatis оператор генерируется методом подготовки объекта RoutingStatementHandler. Следовательно, одной из идей для использования перехватчика для реализации подготовки Mybatis является перехват метода подготовки интерфейса оператора handler, а затем изменить оператор SQL в соответствующий оператор Pagination запрос SQL в методе Interceptor, а затем вызовут метод Prepare объекта * atemberHandler объекта, то есть вызов вызовов. * Для страниц одна из операций, которые мы должны выполнить в перехватчике, - подсчитать общее количество записей, которые соответствуют текущим условиям. Это получает исходное оператор SQL, изменение его на соответствующий статистический оператор, а затем заменить параметры в операторе SQL, используя инкапсулированные параметры Mybatis и параметры настройки *. Затем, оператор SQL, запрашивающий количество записей, выполняется для подсчета общего количества записей. * */ @Intercepts ({ @Signature (type = ratementHandler.class, method = "prepare", args = {connection.class})}) открытый класс PageInterceptor реализует Interceptor {private String dialect = ""; // база данных диалект частной строки pagesqlid = ""; // ID, который необходимо перехватить в mapper.xml (обычное совпадение) общедоступный объект Intercept (вызов вызов), бросает Throwable {// На самом деле существует только два класса реализации для утверждения, один из них - RoutingStatementHandler, а другим является абстрактный класс базовый жесткий. // BasestatementHandler имеет три подкласса, а именно прост, подготовленные, PreditStatementHandler и CallableStatementHandler. // SimpletatementHandler используется для обработки оператора, подготовленного StatatementHandler обрабатывает подготовку, а CallableStatementHandler - // процессы CallableStatement. Mybatis создает RoutingStatementHandler при обработке операторов SQL. В RoutingStatementHandler есть свойство делегата типа // типа оператора. RoutingStatementHandler создаст соответствующий базовый базовый мандлер в соответствии с различными утверждениями, то есть ShadeStatementHandler, // PreditStatementHandler или CallableStatementHandler. В RoutingStatementHandler все методы интерфейса ApportHandler реализуются делегатом, соответствующим называемому делегату. // Мы отметили перехватчик только перехватывает метод подготовки интерфейса оператора с @Signature в классе PageInterceptor. Поскольку Mybatis завершает его через метод плагина Interceptor только при создании RoutingStatementHandler, поэтому целевым объектом, который мы здесь перехватываете, должен быть объектом RoutingStatementHandler. if (vocation.getTarget () encementOf RoutingStatementHandler) {RoutingStatementHandler athipleHandler = (RoutingStatementHandler) vocation.getTarget (); Заявление Handler Delegate = (ratementHandler) ReflecThelper.getFieldValue (attivelhandler, "делегат"); Boundsql boundsql = delegate.getboundsql (); Объект obj = boundsql.getParameterObject (); if (obj exanceof page <?>) {page <?> page = (page <?>) obj; // Извлечение свойства сопоставленного Statatement в базовом старте дефектного родительского класса MapedStatement MapedStatement = (MapedStatement) OffereCthelper.getFieldValue (делегат, «отображение Statement»); // Параметр перехваченного метода подготовки - это соединение соединения соединения соединения = (подключение) vocation.getArgs () [0]; // Получить в настоящее время выполняемый оператор SQL, то есть оператор SQL, который мы пишем непосредственно в строке оператора сопоставления Mapper SQL = BoundSQL.getSQL (); // Установить общее количество записей для текущего объекта параметра страницы this.setTotalRecord (Page, MapedStatement, Connection); // Получить Page SQL -оператор STRING PAGESQL = this.getPagesQL (Page, SQL); // Использовать отражение для установки атрибута SQL, соответствующего текущему BoundsQL, для создания хорошего оператора SQL для US ReflecThelper.SetFieldValue (BoundSQL, «SQL», PagesQL); }} return vlocation.proceedceed (); } /*** Установите общее количество записей для текущей страницы объекта параметра** @param Page Page Mapper оператор сопоставления* @param mapedstatement mapper оператор отображения* @param Соединение Соединение Базы данных* /private void centotalRecord (страница <?> Page, MapedStatement MapedStatement, Connection Connection) {// Получите соответствующий BuldsCL. Это BoundSQL на самом деле является тем же объектом, что и BoundSQL, который мы получили с использованием оператора. // Boundsql в делегате также получается с помощью метода MapedStatement.getBoundSQL (paramoBJ). BoundsQl Boundsql = mapedStatement.getBoundSql (page); // Получить соответствующий оператор SQL string sql = boundsql.getsql (); // Получение соответствующего оператора SQL, который вычисляет общее количество записей, запрашивая оператор SQL String string ountsql = this.getCountsql (sql); // Получить соответствующую карту параметров через список BoundSQL <Parametermapping> parametermAppings = boundsql.getParameterMappings (); // Использование конфигурации, оператор SQL Countsql для запросов записей, параметров параметров параметров параметров и страницы объекта параметров для создания объекта BoundSQL, соответствующего записям запросов. Boundsql countboundsql = new Boundsql (mapedStatement.getConfiguration (), countsql, parametermAppings, page); // Создание объекта параметра -ручка для настройки параметров с помощью отображения Statement, страницы объекта параметра и BoundSQL CountBoundSQL. ParameterHandler ParameterHandler = новый DefaultParameterHandler (MapedStatement, Page, CountBoundSQL); // Создать объект подготовленного предприятия, соответствующий графству, посредством соединения. Подготовленное Statatement pstmt = null; Результат RS = NULL; try {pstmt = connection.preparestatement (ountsql); // Установить параметры параметра и параметра для объекта подготовленного Statatement через параметр handler.setParameters (pstmt); // Затем он выполняется для получения общего количества записей и получения результатов. rs = pstmt.executequery (); if (rs.next ()) {int totalRecord = rs.getint (1); // Установить общее количество записей для текущей страницы параметра object.setTotalRecord (totalRecord); }} catch (sqlexception e) {e.printstacktrace (); } наконец {try {if (rs! = null) rs.close (); if (pstmt! = null) pstmt.close (); } catch (sqlexception e) {e.printstacktrace (); }}} / ** * SQL оператор, который получает соответствующее общее количество записей в запросе * @param sql * @return * / private string getCountsql (string sql) {int index = sql.indexof ("from"); вернуть "Выберите count (*)" + sql.substring (index); } /*** Получить соответствующий запрос на страницу SQL на основе объекта страницы. Здесь производится только два типа базы данных: MySQL и Oracle * Никакие другие базы данных не являются подкреплением * * @param Page Page Object * @param SQL Original SQL оператор * @return */ private String getPagesql (Page <?> Page, String SQL) {StringBuffer SQLBuffer = new StringBuffer (SQL); if ("mysql". EqualsignoreCase (dialect)) {return getMysqlPagesQl (page, sqlbuffer); } else if ("oracle". EqualsIgnoreCase (dialect)) {return getOraclePagesql (page, sqlbuffer); } return sqlbuffer.toString (); } / *** Получите оператор Page Query для базы данных MySQL* @param page page объект* @param sqlbuffer stringbuffer объекта, содержащего исходный оператор SQL* @return MySQL Pagebase Waging Waging Waging Waging Waging Waging Waging Waging Waging wagen Положение записи в MySQL начинается с 0. // system.out.println ("page:"+page.getPage ()+"--------"+page.getRows ()); int offset = (page.getPage () - 1) * page.getRows (); sqlbuffer.append ("Limit") .append (offset) .append (","). Append (page.getrows ()); return sqlbuffer.toString (); } / *** Получить оператор Page Query для базы данных Oracle* @param Page Page Object* @param sqlbuffer stringbuffer объекта, содержащего исходный оператор SQL* @return Pagancation Query для базы данных Oracle* / private String getOraclePagesQL (Page <?> Page, Stringbuffer Sqlbuffer) {// CANCELULE of The First ARICTULE. Oracle Pagination выполняется через Rownum, а Rownum начинается с 1 int offset = (page.getpage () - 1) * page.getrows () + 1; sqlbuffer.insert (0, «Выберите u.*, rownum r from (") .append (") u, где rownum <") .append (offset + page.getrows ()); sqlbuffer.insert (0, "select * from (") .append (") где r> =") .append (offset); // Приведенное выше оператор SQL выглядит следующим образом: // select * from (select u. *, Rownum r из (select * from t_user) u, где rownum <31), где r> = 16 return sqlbuffer.toString (); } / *** Метод для инкапсулирования исходного объекта, соответствующего плагину Interceptor* / public Object (Object arg0) {// todo автоматическое сгенерированное метод if (arg0 antacureOf antainationHandler) {return plugin.wrap (arg0, this); } else {return arg0; }} / *** Установите установленные свойства при регистрации перехвата* / public void setProperties (свойства p) {} public String getDialect () {return dialect; } public void setDialect (String dialect) {this.dialect = dialect; } public String getPagesQlid () {return pagesqlid; } public void setPagesQlid (String pagesqlid) {this.pagesqlid = pagesqlid; }} Конфигурация XML:
<!-Конфигурация программирования интерфейса mybatis-> <Bean> <!-BasePackage Указывает пакет, который будет отсканирован. Установки в этом пакете будут искать. Можно указать несколько пакетов, разделенных с запятыми или полуколонами-> <name = "basepackage" value = "com.yidao.mybatis.dao" /> <name = "sqlSessionFactoryBeanName" value = "sqlSessionFactory" /> < /bean> <! name = "dialect" value = "mysql"/> <!-перехватить оператор с идентификатором, содержащим символы запроса в файле mapper.xml-> <name = "pagesqlid" value = ".*Query $"/> </bean>
Page Class
пакет com.yidao.utils;/** Посмотрите на это самостоятельно, какие поля необходимы для него*/Public Class Page {Private Integer Rows; Частная целочисленная страница = 1; частное целое число TotalRecord; public Integer getRows () {return Rows; } public void setRows (Integer Rows) {this.rows = row; } public integer getPage () {return Page; } public void set -set -page (Integer Page) {this.page = page; } public integer getTotalRecord () {return totalRecord; } public void cetTotOtalRecord (Integer TotalRecord) {this.TotalRecord = totalRecord; }} Отражающий класс
пакет com.yidao.utils; import java.lang.reflect.field; import org.apache.commons.lang3.reflect.fieldutils; public class Reflecthelper {public static object getFieldValue (Object obj, String FieldName) {if (obj = null) {return null; } Field TargetField = getTargetField (obj.getClass (), FieldName); try {return fieldutils.readfield (Targetfield, obj, true); } catch (allogalaccessexception e) {e.printstacktrace (); } return 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 (Exception e) {} Поле возврата; } public static void setFieldValue (Object obj, String FieldName, значение объекта) {if (null == obj) {return;} поле TargetField = getTargetField (obj.getClass (), FieldName); try {fieldutils.writefield (Targetfield, obj, значение); } catch (allogalaccessexception e) {e.printstacktrace (); }}}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.