Depois de trabalhar duro por várias noites para depurar o programa, escrevendo vários blogs e finalmente estabelecendo o mecanismo de expansão para a configuração do Mybatis. Embora o mecanismo de extensão seja importante, pelo menos não é tão inspirador se não há função de extensão verdadeiramente prática. Este blog fornecerá alguns exemplos de extensões.
O motivo deste estudo do código -fonte é a compatibilidade entre os bancos de dados Oracle e MySQL. Por exemplo, usando linhas verticais duplas como conectores no Oracle e usando a função Concat no MySQL; Por exemplo, usando a função Decody no Oracle, enquanto usa apenas o caso padrão quando estiver no MySQL; Por exemplo, exclua a tabela do formulário onde o campo1 em (selecione Field1 Form tabela onde Field2 =?) Pode ser executado, mas exceções serão jogadas no MySQL, etc.
Vamos começar resolvendo esses problemas de compatibilidade. Primeiro, você precisa adicionar configurações relacionadas à identidade do banco de dados à configuração:
<!-Construa objeto de configuração sozinho-> <bean id = "mybatisconfig"/> <bean id = "sqlsessionFactory" p: DataSource-ref = "DataSource"> <!-injete mybatis configuration objeto-> <nome do nome "configuration" = "myBatisconfig"/"screataticatics scratatics (scatataticsnatatics-! name = "mapperLocações"> <Rray> <Value> ClassPath*: **/*. sqlmapper.xml </value> </rays> </propriedade> <!-Database Identification Configuration-> <propriedades name = "DatabaseIdProvider"> <bean> <nome da propriedade " O MySQL é usado como banco de dados na configuração. As palavras -chave de implementação nativa de Mybatis são sensíveis ao caso. Eu não testei o Oracle e o db2 -> <prop key = "mysql"> mysql </prop> <props key = "oracle"> oracle </prop> <props key = "h2"> h2 </prop> <p key = "db2"> db2 </propps> </property> </bean>
1. Problema do conector
1. Escreva a classe de implementação da função de configuração SQL
classe pública concatsqlConfigFunction estende abstratosSqlConfigFunction {// O nível de ordem padrão é definido na classe pai abstrata @OverridePublic string getName () {return "concat";} @substituto de requisição de string (string databaseId, string [] args) {se (se (if (scorns.lchereter <2) {string string (string databaseId, string [] args) {if (ifs.lClength <2) {string. argumentos.2. Registre -se no bloco de código estático da classe Schemahandlers ou ligue para o método Schemahandlers na classe de inicialização de inicialização.
estático {// registra declaração de manipulação ("cache-ref", new cacherefstatementHandler ()); registro ("cache", new cachestatementHandler ()); registro ("parametermap", new parameTerMapstatement ()); registr ("resultMap", newMapStateHandler (); SqlstatementHandler ()); registro ("selecione | inserir | update | delete", new CrudStatementHandler ()); // Registre o namespace padrão scripthandlerRegister ("Trim", new TrimscriptHandler (); registro ("where", New WherScriptHAndLandler ()); ForeachscriptHandler ()); registro ("se | quando", novo ifScriptHandler ()); registro ("escolha", new ChoosescriptHandler ()); // Register ("When", new ifscriptHandler (); registro); recostHand (new BindScriptScriptScriptHand); registro/registro ("Bind); BindSthth (BindStHStHSTHScriptScripts); DbstatementHandler (), new DBScriptHandler ()); // Registre sqlConfigFunctionRegister (new DecodesqlConfigfunction ()); registro (new concatsqlConfigFunction ();); // registre sqlconfigfigfiplity #gister (newsqlconfigfunctory ();Além de registrar o ConcatsqlConfigFunction, o código acima também possui outros códigos de registro, que são fornecidos aqui e serão omitidos abaixo.
3. Modifique a configuração do SQLMapper
<SELECT ID = "SELECTSTRING" ResultType = "String"> Selecione param_name, $ concat {param_code, param_name} como code_name de bf_param_enum_def <se test = "null! = paramname e ''! '%'} </if> </leclect>4. Classe de interface de gravação
@RepositoryPublic Interface iexampledao {public String SelectString (@param ("paramName") String paramname);}5. Escreva aulas de teste
@Runwith (springjunit4classrunner.class) @contextConfiguration (locations = {"classPath: spring/ApplicationContext.xml"})@ComponentPublic Class ExampledAotest {@ReSourcePrivate iexampledao Dao; @testpublic Void TestseltStelStelStLeCtStelTing Dao.SelectString ("Show"); Assert.asserTequals ("Show Area", A);}}6. Corra o seguinte em MySQL e H2, respectivamente (ajuste o nível de log mybatis para rastrear)
(1) MySQL
20161108 00: 12: 55.235 [Main]-[Debug] ==> Preparando: Selecione Param_Name, concat (param_code, param_name) como code_name de bf_param_enum_def onde param_name como concat ('%',?, '%) (String) 20161108 00: 12: 55.287 [main]-[rastreio] <== colunas: param_name, code_name20161108 00: 12: 55,287 [main]-[rastreio] <== linha: área de exibição, exibição_aréia Maior2016111108 00: 12: 55,28.288888888880:(2) H2
20161108 00: 23: 08,348 [main]-[Debug] ==> Preparando: Selecione Param_Name, Param_code || param_name como code_name de BF_PARAM_ENUM_DEF WHERE Param_Name como '%' ||? | 00: 23: 08,411 [main]-[rastreio] <== colunas: param_name, code_name20161108 00: 23: 08,411 [main]-[rastreio] <== Linha: Display Area, Display_area Display Area20161108: 23: 08,411 [main]-[Debug] <Arming Area20161108: 23: 08,411 [Main]-[Debug] <Arbug] <Arming Area20161108: 23: 08,411 [Main]-[Debug] <Arbug] <Arming Area20161108: 23: 08,411 [Main]-[Debug] <Arbug] <Arming Area20161108: 23: 08,411 [main]
Como você pode ver, a questão da compatibilidade dos conectores foi resolvida.
Além disso, também descobrimos que a escrita é mais problemática ao usar palavras -chave semelhantes, então vamos dar um novo conjunto de funções de configuração do SQL:
public class LikeSqlConfigFunctionFactory implements ISqlConfigFunctionFactory{@Overridepublic Collection<ISqlConfigFunction> getSqlConfigFunctions() {return Arrays.asList(getLeftLikeSqlConfigFunction(), getRightLikeSqlConfigFunction(), getLikeSqlConfigFunction());}private IsqlConfigfunction getLeftlikesqlConfigfunction () {retorna new abstratelikesqlConfigfunction () {@SubstridePublic string getName () {return "l -like";}@@EvernidePublf String Eval (string arg) {Return {como $ concat {'%', ""+" getrightlikesqlConfigfunction () {retorna new abstratelikesqlConfigFunction () {@substituir String string getName () {return "rlike";}@substituição string de string (string arg) {return "como $ concat {"+arg+", '%'}";};}; getlikesqlConfigFunction () {retorna new abstratelikesqlConfigFunction () {@SubsteridePublic String getName () {return "like";}@substituição String prototeged Eval (string arg) {return "como $ concat {'%',"+arg+", '%'}"};};}; AbstractSqlConfigFunction{@Overridepublic String eval(String databaseId, String[] args) {if(args.length != 1){Throw.throwException("the like function requires one and only one argument.");}return eval(args[0]);}protected abstract String eval(String arg);}}Aqui, um conjunto de funções de configuração SQL é definido, com similaridade esquerda, similaridade direita e correspondência de similaridade média, e as funções de configuração do SQL também podem ser aninhadas. Portanto, o arquivo de configuração do SQLMapper é simplificado para:
<select id = "SelectString" resultType = "String"> Selecione Param_Name, $ concat {param_code, param_name} como code_name de bf_param_enum_def <se test = "null! = paramname e '!Os resultados da execução são exatamente iguais.
Se você ainda achar problemático, porque param_name e Paramname são correspondências semelhantes a camelos, você pode até adicionar uma função em campo e modificar a configuração para
onde $ fieldlike {#{param_name, jdbctype = varchar}}Se combinado com o dicionário de dados, a configuração JDBCTYPE também pode ser gerada automaticamente:
onde $ fieldlike {#{param_name}}Nesse caso, se houver vários parâmetros, não haverá ambiguidade (ou uma função de configuração recém -definida $ curtidas {} será usada para eliminar a ambiguidade), para que várias condições possam ser simplificadas para:
onde $ gosta {#{param_name, param_name2, param_name3}}Obviamente, existem mais simplificações digitáveis que não estão mais apenas no escopo da compatibilidade, por isso não iremos mais longe aqui.
2. Decodificar função/caso ... quando
A função de decodificação no Oracle é muito conveniente, e a sintaxe é a seguinte:
Decodificar (condição, valor 1, valor de retorno 1, valor 2, valor de retorno 2, ... valor n, valor de retorno n [, valor padrão]))
Escrita padrão de equivalentes:
Condição do caso quando o valor 1 e depois retornar o valor 1 quando o valor 2 e depois retornar o valor 2 ... quando o valor n e depois retornar o valor n [else padrão]
Agora vamos implementar uma função de configuração de decodificação $:
public class DecodeSqlConfigFunction extends AbstractSqlConfigFunction{@Overridepublic String getName() {return "decode";}@Overridepublic String eval(String databaseId, String[] args) {if(args.length < 3){Throw.throwException("the decode function requires at least three argumentos. ") .apend (args [0]); int i = 2, l = args.length; para (; i <l; i = i+2) {sb.append (" when ") .append (args [i-1]). sb.append ("else") .append (args [l-1]);} sb.append ("end"); retorna sb.toString ();}}}Em seguida, use Schemahandlers para registrar e modificar a configuração no SQLMAPPPER:
<select id = "Selecione" ResultType = "String"> Selecione param_name, $ decodge {#{paramname}, '1', 'a', '2', 'b', 'c'} como decodificador_test de bf_param_enum_enum_def <se test = "null! = paramname e '! jdbctype = varchar}} </if> </select>Os testes são os seguintes:
(1) Em H2 (substitua o Oracle por H2)
20161108 06: 53: 29.747 [Main]-[Debug] ==> Preparando: Selecione Param_Name, decode (?, '1', 'A', '2', 'B', 'C') como Decode_test de BF_PARAM_ENUM_DEF onde param_name como '%' ||?
(2) em MySql
20161108 06: 50: 55.998 [Main]-[Debug] ==> Preparando: Selecione Param_Name, caso? Quando '1', então 'a' quando '2' então 'b' else 'c' termina como decode_test de bf_param_enum_def onde param_name como '%' ||? || '%'
O acima exposto é uma introdução detalhada à extensão e aplicação da configuração do SQLMAPPER no Mybatis apresentado a você pelo editor (1). Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!