Compreender os princípios subjacentes corrida analítica artigo MyBatis

Dicas: O foco deste artigo é MyBatis resolvidos executar um processo de sql, o processo de comparação pensamento jumping, relativamente raro que você pode ver um resumo de fonte descem


 

O artigo para resolver MyBatis executar uma sql através de um processo de execução da instrução de inserção. Fundo, de fonte MyBatis-3.0.5.jar,

MyBatis-config.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC 
	"-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<properties resource="jdbc.properties" />
	<!-- 配置别名 -->
	<typeAliases>
		<typeAlias type="dao.DataDao" alias="DataDao" />
	</typeAliases>
	 
	<!-- 配置环境变量 -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driverClass}" />
				<property name="url" value="${jdbcUrl}" />
				<property name="username" value="${DBusername}" />
				<property name="password" value="${DBpassword}" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 配置mappers -->
	<mappers>

		<mapper resource="dao/DataDao.xml" />
	</mappers>
	
</configuration>   

mapeador interface correspondente:

public interface DataDao {

    public  int mysqlInsert(Map<String, Object> map) throws Exception;
}

Correspondente ao DataDao.xml de interface:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.DataDao">
   <insert id="mysqlInsert" parameterType="map" >
		insert into ${tableName}
		(${columns})
		values
		(${colValues})
	</insert>
</mapper>

Primeiro, vamos vir a interpretar a entrada de onde MyBatis carregado, olhar para uma MyBatis inserir o código:

/**
     * 传入map参数,执行插入
     * @param map
     * @return
     */
    public static int mysqlInsert(Map<String, Object> map) throws Exception {
        SqlSession session = null;
        int index=0;
        try {
            session = SessionFactory.getSession();
            DataDao dataDao = session.getMapper(DataDao.class);
            index=dataDao.mysqlInsert(map);
            if(index>0){
                logger.info("insert success: "+index);
            }
             session.commit(true);
        } catch (Exception e) {
            logger.error("插入异常:", e);
            session.rollback(true);
            throw e;
        } finally {
            session.close();
        }
        return index;
    }
public class SessionFactory {

    private static Logger logger =  LoggerFactory.getLogger(SessionFactory.class);

    private static SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
    private static SqlSessionFactory sqlSessionFactory;

        //初始化mybatis
        static {
            String resource = "mybatis-config.xml";
            Reader reader = null;
            try {
                reader = Resources.getResourceAsReader(resource);
                sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
                sqlSessionFactory = sqlSessionFactoryBuilder.build(reader);
            } catch (IOException e) {
                logger.error("加载配置文件错误:",e);
                e.printStackTrace();
            }catch (Exception e){
                logger.error("加载配置文件错误:",e);
            }

            logger.info("init mybatis");
        }

    public  static synchronized SqlSession getSession() throws IOException {
        SqlSession sqlSession =null;
        if(null == sqlSession) {
            sqlSession = (null != sqlSessionFactory)?sqlSessionFactory.openSession(): null;
        }
        return sqlSession;
    }

}

Você pode ver o código vai primeiro passar por obter SqlSession SessionFactory, que haverá um código estático quando o carregador de classe SessionFactory irá executar o processo de inicialização MyBatis-config.xml. Agora vamos olhar diretamente concentrar-se: 

DataDao interface de aquisição de dados através SqlSession de tempo getMapper encontrou duas datas de implementação voltar para a inicialização SessionFactory verá o seguinte parágrafo:

Então, nós vamos diretamente ao método DefaultSqlSession getMapper pode ser encontrado em MapperRegistry:

Veja aqui os amigos familiares proxies dinâmicos saber que este é escrito em java para obter uma classe proxy dinâmico (ps: não familiarizados com o proxy dinâmico, você pode ver aqui meu último blog  proxy dinâmico vernacular resolvido ), continuamos a olhar para baixo :

Continuar a ir ao próximo passo: dataDao.mysqlInsert (mapa); MapperProxy chama invocação método de realizar este método:

Além do objeto método open-source ver a agência não pode, o outro virá mapperMethod.execute (args):

campo de tipo será avaliada quando mapperMethod inicialização, onde realizamos inserção, método de atualização DefaultSqlSession continuar a descer;

Depois aqui, então nós começamos a ver a inicialização configuração, configuração quando é SqlSessionFactory inicializado

A descrição acima pode ser visto Configuração 2 do código é inicializado pelo carregamento MyBatis-config.

Agora vamos voltar para this.configuration.getMappedStatement (declaração); este código:

Vai olhar descobrimos que ele é, de fato, para obter a MappedStatement correspondente por id, pelo exposto, podemos ver id é passado na execução MapperMethod método do commandName, ele setupFields método no construtor para inicializar MapperMethod em:

Valores aqui: DataDao.mysqlInsert. Tal como esse, que é o nome do método classe de interface.

Agora vamos voltar para o fluxo principal, veja mappedStatements inicialização processo é this.mapperElement (root.evalNode ( "mapeadores")) na inicialização configuração acima; in: 

Aqui parses sql mapper.xml nó no exemplo deste artigo é:

Nós continuamos a ver os mappedStatements de inicialização:

id aqui podemos ver que o valor de namespace.id emenda de nós, isto é DataDao.mysqlInsert

 

Agora vamos continuar a voltar para o fluxo principal, olhar para este código:

Atualização execução de código método pelo executor, e agora olhamos executor do processo de inicialização é um processo em inicialização SqlSession:

No construtor de configuração pode ser visto aqui executorType padrão é simples, padrão cacheEnabled é verdade.

Agora vamos continuar a voltar para o fluxo principal, no CachingExecutor método de atualização em:

Aqui entra o método de atualização BaseExecutor

Aqui nós entrará em SimpleExecutor de DoUpdate em:

Aqui primeira inicializa um RoutingStatementHandler, resulta do padrão statementType acima PREPARADO, portanto, a propriedade delegado do PreparedStatementHandler. Voltamos para o fluxo principal, continuar a olhar this.prepareStatement (manipulador):

Eu virei para preparar o BaseStatementHandler método: 

Aqui nós entrará em instantiateStatement método PreparedStatementHandler de:

boundSql aqui é que quando na inicialização mappedStatement acima de atribuição:

 

O primeiro é inicializado em parseStatementNode DynamicSqlSource, então, fazer BoundSql, então olhamos parseDynamicTags método XMLStatementBuilder de:

Podemos ver se o código não é nem um tipo de nó nó de texto não é CDATA nó será chamado para lidar com um tipo diferente de tratamento, mais comumente usado é o <if> e <em> nós utilizados na consulta, onde realizamos é inserção, é um nó de texto directamente, o seguinte é o de inicialização e de configuração de uma MixedSqlNode construído DynamicSqlSource, então construído pelo método getBoundSql BoundSql:

 A partir do exposto conhecido: rootSqlNode é MixedSqlNode, esse método realiza a aplicar MixedSqlNode, nas presentes formas de realização executa o TextSqlNode aplicar

métodos:

Esta secção é utilizada principalmente para processá-lo no SQL parâmetro espaço reservado $ {}, aqui a inserção em $ {tableName} ({colunas} $) valores ($ {colValues}) após inserção de análise de conversão na tabela (ID , nome) valores (1, 'teste'), esta secção de código é não analisadas, relativamente complicado, principalmente através do espaço reservado correspondente é substituído com o valor correspondente.

Nós voltar ao método getBoundSql, continuar a ir para baixo, para sqlSourceParser.parse (context.getSql (), parameterType) esta linha de código: 

Vi código familiar, o que é uma seção # {} espaço reservado é substituído por um valor correspondente.

Continuamos a voltar para o fluxo principal instantiateStatement método PreparedStatementHandler acima, e vá abaixo:

Jdbc3KeyGenerator aqui é que, se definir useGeneratedKeys = verdadeiro chave principal utilizado para gerar automaticamente, de acordo com a presente forma de realização também não é ResultsetType refere-se vazia, de modo que haverá um retorno para o PreparedStatement, aqui DoUpdate do nosso SimpleExecutor this.prepareStatement (manipulador)

Esta análise de código concluída.

Voltamos para o fluxo principal continuar a descer;

Aqui, o processo prossegue para executar o PreparedStatement JDBC executa a inserção de operações de inserção. 2 do código atrás Não analisada, utilizada principalmente para obter a chave primária.

Aqui, MyBatis executar um mecanismo de operação SQL insert em análise é completa.

 

resumo:

 No processo de análise de código fonte, pode ser mais salto, porque vai haver alguma inicialização ou classe de configuração de classe de execução no processo de análise de código fonte. Aqui para compartilhar o código fonte para ler maneira rápida de ver o código fonte no processo, pode haver muitas extensões, calibração, código de inicialização para algumas funções, tais como:

   classe 1. Configuração de Inicialização

   2. Execute Interceptor interceptor (na verdade, usa uma cadeia de padrões de projeto de responsabilidade e criar padrões para alcançar proxies dinâmicos interceptar)

   3. Cache Cache implementações

Pode temporariamente ignorar, primeiro vá sobre o fluxo principal do código, como MyBatis realizar um processo sql pode ver o código fonte da seguinte forma:

 

Quando vemos todo o processo para alcançar claro, se você quiser ver mais detalhes, você pode usar o outro a tempo de ver a implementação de trás da funcionalidade estendida

Publicado 25 artigos originais · ganhou elogios 51 · vê 20000 +

Acho que você gosta

Origin blog.csdn.net/Royal_lr/article/details/88883890
Recomendado
Clasificación