ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Mybatis的使用与源码分析

2022-07-06 18:11:24  阅读:188  来源: 互联网

标签:分析 builder mybatis ibatis apache 源码 ms Mybatis org


1.Mybatis整合到SpringBoot项目

1.1 引入依赖

如果使用最基础级mybatis,使用以下依赖:

<!-- mybatis依赖-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>${mybatis.version}</version>
</dependency>

如果使用通用mapper,使用以下依赖:

<!-- 通用mapper依赖 -->
<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>${version}</version>
</dependency>

如果使用mybatis-plus,使用以下依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${version}</version>
</dependency>

如果使用mybatis-plus插件生成代码,使用以下依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>${version}</version>
</dependency>
<!-- 以下依赖与选择的代码模板引擎有关,不同引擎选择不同模板-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>${version}</version>
</dependency>

1.2 增加Config

@Configuration
public class MybatisConfig {

    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;

    @Bean
    public SqlSessionFactoryBean configSqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 时候输出mybatis相关日志
        configuration.setLogImpl(StdOutImpl.class);
        // 开启驼峰命名
        configuration.setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setConfiguration(configuration);
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 设置pageHelper分页插件
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
     // 指定数据库方言
        properties.setProperty("dialect", dialect);
        pageHelper.setProperties(properties);
        sqlSessionFactoryBean.setPlugins(pageHelper);
        // 设置mapper.xml路径
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));// 设置mapper文件扫描路径
        return sqlSessionFactoryBean;
    }
}

2.Mybatis的核心流程

XML处理相关的类

一、XMLConfigBuilder用来解析mybatis的核心配置文件文件xml中的节点,然后封装到Configuration类中;
二、XMLMapperBuilder用来解析mybatis中Mapper的xml文件,获取到所有节点为<select>|<insert>|<update>|<delete>的节点,然后通过XMLStatementBuilder类来解析这些节点,最后通过MapperBuilderAssistant类来转成MappedStatment对象,添加到Configuration中。

2.1 SqlSessionFactoryBuilder

负责创建SqlSessionFactory。主要解析出MybatisConfig.xml中数据数据库连接信息和Mapper.xml文件,封装成MappedStatement对象。
org.apache.ibatis.session.SqlSessionFactoryBuilder#build
org.apache.ibatis.builder.xml.XMLConfigBuilder#parse
sqlSessionFactory1
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
sqlSessionFactory2

2.2 SqlSessionFactory

负责创建SqlSession,并指定SqlSession的执行器,环境,事务管理器,事务提交机制。
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
sqlSession1
org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
sqlSession2

2.3 SqlSession

1.负责调用getMapper方法生成代理对象,并执行对应的代理对象调用方法的具体sql语句
org.apache.ibatis.binding.MapperRegistry#getMapper
生成mapper代理类1
org.apache.ibatis.binding.MapperProxyFactory#newInstance
生成mappr代理类2

2.4 ParameterHandler

负责将用户传递的参数转换成JDBC Statement需要的参数
org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters
解析传入的参数

2.3 StatementHandler

负责对JDBC Statement的操作,如Statement执行查询、更新
org.apache.ibatis.executor.statement.PreparedStatementHandler#query
statementHandler1
statementHandler2

2.6 ResultSetHandler

负责将JDBC返回的ResultSet结果集转换成对象或List类型的集合
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleRowValuesForSimpleResultMap
解析返回结果集

2.7 Executor

Mybatis执行器,负责Sql语句的执行和查询缓存的维护
org.apache.ibatis.executor.CachingExecutor#query
executor

3.Mybatis的插件使用

3.1 自定义插件完成sql语句的输出和进行排序

<!-- 需要加入mybatisConfig.xml中的配置-->
<plugins>
    <plugin interceptor="com.two.dream.interceptor.ZdyPlugin"></plugin>
</plugins>

如果是springboot项目直接: sqlSessionFactoryBean.setPlugins(new ZdyPlugin());

@Intercepts({@Signature(
        type = Executor.class, //拦截的接口
        method = "query", // 拦截的方法
        args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} // 拦截方法的入参的参数类型
)})
public class ZdyPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("=========Executor===========");
        // 获取拦截方法的参数
        Object[] args = invocation.getArgs(); 
        MappedStatement mappedStatement = (MappedStatement) args[0];
        Configuration configuration = mappedStatement.getConfiguration();
        // 输出原sql语句
        SqlSource sqlSource = mappedStatement.getSqlSource();
        BoundSql boundSql = sqlSource.getBoundSql(args[1]);
        System.out.println(boundSql.getSql());
        System.out.println("==========================");
        // 修改原sql语句
        SqlSource newSqlSource = new StaticSqlSource(configuration, boundSql.getSql().concat(" order by address desc"), boundSql.getParameterMappings());
        MappedStatement newMappedStatement = this.build(mappedStatement, newSqlSource);
        // 修改原参数对象
        args[0] = newMappedStatement;
        // 输出修改后的sql
        System.out.println(newSqlSource.getBoundSql(args[1]).getSql());
        return invocation.proceed();
    }

    private MappedStatement build(MappedStatement ms, SqlSource newSqlSource){
        // 拷贝原对象的属性到新对象
        MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultSetType(ms.getResultSetType());
        builder.resultMaps(ms.getResultMaps());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());
        return builder.build();
    }
}

标签:分析,builder,mybatis,ibatis,apache,源码,ms,Mybatis,org
来源: https://www.cnblogs.com/fallmwu/p/13932790.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有