После упорного труда в течение нескольких ночей, чтобы отлаживать программу, написание нескольких блогов и, наконец, установить механизм расширения для конфигурации Mybatis. Хотя механизм расширения важен, он, по крайней мере, не настолько вдохновляет, если нет действительно практической функции расширения. Этот блог даст вам несколько примеров расширений.
Причиной этого исследования исходного кода является совместимость между базами данных Oracle и MySQL. Например, использование двойных вертикальных линий в качестве разъемов в Oracle и использование функции CONCAT в MySQL; Например, использование функции декодирования в Oracle, в то время как использование стандартного случая только в MySQL; Например, таблица удаления форм, где можно выполнить Field1 in (выберите Field1 Form, где Field2 =?) может быть выполнено, но исключения будут брошены в MySQL и т. Д.
Давайте начнем с решения этих проблем совместимости. Во-первых, вам необходимо добавить конфигурации, связанные с идентификацией базы данных, в конфигурацию:
<!-Способность построить объект конфигурации самостоятельно-> <bean id = "mybatisconfig"/> <bean id = "sqlSessionFactory" p: dataSource-ref = "dataSource"> <!-Inject Mybatis Configuration объект-> <properation name = "configuration" ref = "mybatisfig"/> <! name = "mapperlocations"> <array> <datter> classpath*: **/*. sqlmapper.xml </value> </array> </property> <!-Конфигурация идентификации продукта базы данных-> <property name = "DatabaseIdprovider"> <Bean> <property name = "> <Props> <! MySQL используется в качестве базы данных в конфигурации. Ключевые слова Mybatis Native Regaination чувствительны. Я не тестировал Oracle и DB2 -> <prop key = "mysql"> mysql </prop> <prop key = "oracle"> oracle </prop> <prop key = "h2"> h2 </prop> <prop key = "db2"> db2 </prop> </props> </property> </bean>
1. Проблема разъема
1. Напишите класс реализации функции конфигурации SQL
открытый класс concatsqlConfigfunction extends AbstractSQlConfigFunction {// Уровень порядка по умолчанию устанавливается в абстрактном родительском классе @OverridePublic String getName () {return "concat";} @overridepublic string eval. Аргументы. ");} if (" mysql ".equalsignorecase (databaseid)) {return" concat ("+tool.string.join (args,", ")+") ";} else {return tool.string.join (args," || ");2. Зарегистрируйтесь в статическом кодовом блоке класса Schemahandlers или вызовите метод схемахандлеров в классе инициализации запуска.
static {// Register atportionHandlerRegister ("cache-ref", new CacherefstatementHandler ()); Register ("Cache", New CachestatementHandler ()); Register ("Parametermap", New ParametermapStatementHandler (); Register ("ResultMap", New ResultMapTatementHandler (). SQLStatementHandler ()); Register («SELECT | INSERT | UPDATE | DELETE», New CrudStatementHandler ()); // Зарегистрировать пространство имен по умолчанию («Trim», «Trim», New TrimscripThandler ()); Register («где», NewScripThandler (), «Register» («SET», NewScripThandler (). ForeachScripThandler ()); Register («if | when», new ifscripthandler ()); Register («Выберите», New Choescripthandler ()); // Register («Когда», новый ifscripthandler ()); Register («В противном случае», new wetresscripthandler (); «связывать» (Bindscripthandler (); RegisterExtend («DB», New DBStatementHandler (), New DBScripThandler ()); // Регистрация sqlConfigfunctionRegister (new DecodesqlConfigfunction ()); Register (new ConcatsQlConfigfunction ()); // registerConfuctionFactoryRegystory (new LikeSqlConfuction);В дополнение к регистрации concatsqlConfigfunction, приведенный выше код также имеет некоторые другие регистрационные коды, которые приведены здесь и будут опущены ниже.
3. Измените конфигурацию SQLMapper
<select id = "selectString" resultType = "string"> select param_name, $ concat {param_code, param_name} как code_name from bf_param_enum_def <if test = "null! = paramname и '' '! '%'} </if> </select>4. Написать интерфейс класс
@RepositoryPublic Interface Iexampledao {public String selectString (@param ("paramname") String paramname);}5. Напишите тестовые классы
@Runwith (springjunit4classrunner.class) @contextconfiguration (locations = {"classpath: spring/applicationcontext.xml"})@componentpublic class exampledaotest {@resourceprivate iexampledao dao; @testpublic void testselectstring () dao.selectstring ("show"); assert.assertequals ("show area", a);}}6. Запустите следующее в MySQL и H2 соответственно (отрегулируйте уровень журнала Mybatis, чтобы отследить)
(1) MySQL
20161108 00: 12: 55,235 [main]-[Debug] ==> Подготовка: выберите Param_Name, concat (param_code, param_name) как code_name из bf_param_enum_def, где param_name как concat ('%',?, '%') 20161108 00: 12: 55,269 ['%',?, '%') 20161108 00: 12: 55,269 ['%',?, '%') 20161108 00: 12: 55,269 (String) 20161108 00: 12: 55,287 [Main]-[трасса] <== Столбцы: param_name, code_name20161108 00: 12: 55,287 [Main]-[Trace] <== ряд: область дисплея, область Display_area Difle20161108 00: 12: 55,289 [Main].(2) H2
20161108 00: 23: 08,348 [main]-[debug] ==> Подготовка: выберите Param_Name, param_code || param_name as Code_Name от bf_param_enum_def, где param_name как '%' || 00: 23: 08,411 [Main]-[трассировка] <== Столбцы: param_name, code_name20161108 00: 23: 08,411 [main]-[трассировка] <== row: display aem, display_area display20161108 00: 23: 08,411 [Main]-[Debuug] <==.
Как видите, проблема совместимости разъемов была решена.
Кроме того, мы также обнаружили, что написание более хлопотно при использовании ключевых слов, поэтому давайте дадим ему новый набор функций конфигурации SQL:
public class LikeSqlConfigFunctionFactory implements ISqlConfigFunctionFactory{@Overridepublic Collection<ISqlConfigFunction> getSqlConfigFunctions() {return Arrays.asList(getLeftLikeSqlConfigFunction(), getRightLikeSqlConfigFunction(), getLikeSqlConfigFunction());}private IsQlConfigFunction getLeftLikesqlConfigFunction () {return new AbstractLikeSqlCONFIGFUNCTION () {@overdePublic string getName () {return "llike";}@overpublic string eval (string arg) {return "$ concat {'%',"+arg+"}"; GetrightLikesqlConfigFunction () {return new AbstractLikESqlConfigFunction () {@overridePublic string getName () {return "rlize";}@переопределенная строка Eval (String arg) {return "как $ concat {+arg+", '%'}};} private isqlonfint getLikeSqlConfigFunction () {return new AbstractLikESQLConfigFunction () {@overridePublic string getName () {return "like";}@overdeProtected String eval (String arg) {return "как $ concat {'%',"+", '%'}";}}; AbstractSQLConfigFunction {@OverridePublic String string Eval (String DatabaseId, String [] args) {if (args.length! = 1) {throw.ThrowException («Подобная функция требует единого и единственного одного аргумента.»);} Return Eval (args [0]);} Atratect Abstract string Eval (строка arg);}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}Здесь определяется набор функций конфигурации SQL, с левым сходством, правым сходством и сопоставлением среднего сходства, а функции конфигурации SQL также могут быть вложены. Следовательно, файл конфигурации SQLMapper упрощен:
<SELECT ID = "SELECTSTRING" RESTADTYPE = "string"> SELECT PARAM_NAME, $ concat {param_code, param_name} как code_name из bf_param_enum_def <if test = "null! = paramname и '' '!Результаты пробега точно такие же.
Если вы все еще находите его проблемным, потому что Param_Name и ParamNam
где $ fieldlike {#{param_name, jdbctype = varchar}}При сочетании с словарем данных, конфигурация JDBCTYPE также может быть автоматически сгенерирована:
где $ fieldlike {#{param_name}}В этом случае, если есть несколько параметров, не будет никакой двусмысленности (или вновь определенная функция конфигурации $ likes {} будет использоваться для устранения двусмысленности), поэтому несколько условий могут быть упрощены до:
где $ нравится {#{param_name, param_name2, param_name3}}Конечно, существует больше копающих упрощений, которые больше не находятся в сфере совместимости, поэтому мы не пойдем здесь.
2. Декодировать функцию/случай ... когда
Функция декодирования в Oracle очень удобна, а синтаксис выглядит следующим образом:
Декод (условие, значение 1, возвращаемое значение 1, значение 2, возвращаемое значение 2, ... значение n, возвращаемое значение n [, значение по умолчанию])
Стандартное написание эквивалентов:
Условие случая, когда значение 1, затем возвращаемое значение 1 Когда значение 2, затем возвращаемое значение 2 ... когда значение n, затем возвращаемое значение n [else default] Конец
Теперь давайте реализуем функцию конфигурации $ декодирования:
открытый класс decodesqlconfigfunction extends arthactsqlconfigfunction {@overridepublic string getName () {return "decode";}@over -public string eval (string databaseid, string [] args) {if (args.length <3) {throwexcept Аргументы. ");} if (" h2 ".EqualsIgnoreCase (databaseId)) {// при тестировании используйте H2 вместо Oracle и измените его на OraclerTurn в официальной программе" decode ("+tool.String.join (args,", ")+") ";} else {StringBuffer sb = new StringBuffer ();" SaseB.P.); ").append(args[0]);int i=2, l = args.length;for(; i < l; i= i+2){sb.append(" WHEN ").append(args[i-1]).append(" THEN ").append(args[i]);}if(i == l){//When ending the loop, the two are equal to indicate that the last parameter is not used sb.append ("else") .append (args [l-1]);} sb.append ("end"); return sb.tostring ();}}}Затем используйте схемахандлеры для регистрации и изменения конфигурации в SQLMapper:
<SELECT ID = "SELECTSTRING" RESTORATYPE = "string"> select param_name, $ decode {#{paramname}, '1', 'a', '2', 'b', 'c'} as decode_test из bf_param_enum_def <if test = null! jdbctype = varchar}} </if> </select>Тесты следующие:
(1) В H2 (замените Oracle на H2)
20161108 06: 53: 29,747 [main]-[debug] ==> Подготовка: выберите Param_name, Decode (?, '1', 'a', '2', 'b', 'c') как decode_test from bf_param_enum_def, где param_name нравится '%' ||
(2) В MySQL
20161108 06: 50: 55,998 [main]-[Debug] ==> Подготовка: выберите Param_Name, Case? Когда «1», тогда «a», когда '2', затем 'b' else 'c' ed as decode_test из bf_param_enum_def, где param_name like '%' ||? || '%'
Выше приведено подробное введение в расширение и применение конфигурации SQLMAPPER в Mybatis, представленном вам редактором (1). Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит вам вовремя. Большое спасибо за вашу поддержку сайту wulin.com!