mybatis的运行原理和查询实现

发布时间:2021-06-22 15:15:26 作者:chen
来源:亿速云 阅读:137
# MyBatis的运行原理和查询实现

## 一、MyBatis概述

MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作,通过简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(Plain Old Java Objects)映射成数据库中的记录。

### 核心特点
- **轻量级**:与Hibernate相比,MyBatis更加轻量,学习曲线平缓
- **SQL可控**:开发者可以直接编写原生SQL,灵活优化
- **结果集映射**:自动将JDBC ResultSet映射为Java对象
- **插件机制**:提供Interceptor接口支持自定义扩展

## 二、MyBatis整体架构

![MyBatis架构图](https://mybatis.org/images/mybatis-architecture.png)

### 1. 基础支撑层
- **类型转换**:TypeHandler体系处理Java类型与JDBC类型转换
- **日志模块**:集成多种日志框架(SLF4J、Log4j2等)
- **反射工具**:MetaObject、MetaClass等反射工具类
- **资源加载**:ClassLoaderWrapper处理资源文件加载

### 2. 核心处理层
- **配置解析**:XMLConfigBuilder解析mybatis-config.xml
- **SQL解析**:XMLMapperBuilder处理Mapper.xml文件
- **SQL执行**:Executor、StatementHandler、ParameterHandler、ResultSetHandler
- **缓存机制**:一级缓存(SqlSession级别)和二级缓存(Mapper级别)

### 3. 接口层
- **SqlSession**:核心接口,提供CRUD API
- **Mapper接口**:动态代理实现的DAO接口

## 三、MyBatis运行原理

### 1. 初始化阶段
```java
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  1. 配置文件解析

    • 解析mybatis-config.xml构建Configuration对象
    • 注册类型别名、类型处理器、插件等
    • 加载mapper.xml文件,解析SQL语句为MappedStatement
  2. SqlSessionFactory构建

    • 使用Configuration对象创建DefaultSqlSessionFactory

2. 运行时阶段

try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUser(1L);
}
  1. SqlSession创建

    • 通过ExecutorType指定执行器类型(SIMPLE/REUSE/BATCH)
    • 创建Transaction事务对象
    • 初始化Executor执行器(可能包含缓存装饰)
  2. Mapper代理生成

    • 通过MapperProxyFactory创建动态代理
    • 调用MapperMethod.execute()方法路由到具体SQL执行
  3. SQL执行流程

    MapperProxy -> MapperMethod -> SqlSession -> Executor 
    -> StatementHandler -> ParameterHandler -> ResultSetHandler
    

四、查询实现机制

1. 查询执行流程

  1. 参数处理

    • 使用TypeHandler处理Java对象到JDBC参数的转换
    • 通过ParameterMapping处理命名参数(#{param})
  2. SQL预处理

    • StatementHandler创建PreparedStatement
    • 对SQL进行预编译和参数设置
  3. 结果集映射

    • ResultSetHandler处理结果集
    • 根据ResultMap进行自动映射或嵌套映射

2. 核心组件协作

组件 职责
Executor 执行器,调度StatementHandler
StatementHandler 处理SQL语句(prepare/parameterize)
ParameterHandler 设置预处理参数
ResultSetHandler 处理结果集映射

3. 缓存机制

一级缓存: - 默认开启,SqlSession级别 - 同一个SqlSession中相同查询直接返回缓存 - 执行update/commit/rollback时会清空缓存

二级缓存: - 需要手动配置开启 - Mapper级别,多个SqlSession共享 - 通过CacheExecutor实现装饰器模式

五、高级查询特性

1. 动态SQL

<select id="findUsers" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">AND name = #{name}</if>
    <if test="age != null">AND age = #{age}</if>
  </where>
</select>

实现原理: - 使用XMLScriptBuilder解析动态标签 - 生成SqlNode树结构(IfSqlNode/WhereSqlNode等) - 执行时动态拼接SQL

2. 关联查询

嵌套查询

<resultMap id="blogResultMap" type="Blog">
  <association property="author" column="author_id" 
               select="selectAuthor"/>
</resultMap>

嵌套结果

<resultMap id="blogResultMap" type="Blog">
  <id property="id" column="id"/>
  <association property="author" resultMap="authorResultMap"/>
</resultMap>

3. 分页实现

物理分页

PageHelper.startPage(1, 10);
List<User> users = userMapper.selectAll();

原理: - 通过PageInterceptor拦截Executor - 自动改写SQL添加LIMIT子句

六、性能优化建议

  1. 合理使用缓存

    • 读多写少的场景开启二级缓存
    • 避免缓存大对象
  2. SQL优化

    • 使用复用SQL片段
    • 避免N+1查询问题
  3. 批处理

    try(SqlSession session = sessionFactory.openSession(ExecutorType.BATCH)){
       UserMapper mapper = session.getMapper(UserMapper.class);
       for(int i=0;i<1000;i++){
           mapper.insert(user);
       }
       session.commit();
    }
    
  4. 延迟加载

    <setting name="lazyLoadingEnabled" value="true"/>
    

七、总结

MyBatis通过精巧的架构设计,在保持灵活性的同时提供了高效的数据库访问能力。其核心优势在于: 1. 将SQL控制权交还给开发者 2. 通过智能的结果集映射减少样板代码 3. 可扩展的插件体系 4. 多层次的缓存策略

理解MyBatis的运行原理和查询实现机制,有助于开发者编写更高效的持久层代码,并能针对特定场景进行深度优化。随着MyBatis 3的不断演进,其在复杂查询、动态SQL等方面的表现愈发强大,成为Java生态中持久层框架的重要选择。 “`

注:实际字数为约2100字,包含: 1. 架构原理分析 2. 核心流程解析 3. 查询实现细节 4. 优化实践建议 如需调整具体内容或补充某些技术细节,可以进一步修改完善。

推荐阅读:
  1. 深入浅出MyBatis:MyBatis解析和运行原理
  2. ​mybatis实现like查询的方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatis

上一篇:kubernetes中怎么安装Jenkins

下一篇:PHP实现约瑟夫环问题的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》