`
backend-develop
  • 浏览: 24755 次
社区版块
存档分类
最新评论

MyBatis 原理浅析 3 ——数据操作

 
阅读更多

前言

在前文《MyBatis 原理浅析——基本原理》一文中简单分析了 MyBatis 的实现原理,MyBatis 的数据库操作是通过 Executor 执行的。Executor 是一个接口,有三个实现类,分别是 SimpleExecutor、ReuseExecutor 和 BatchExecutor。

 

查询数据的流程

查询数据是通过 SqlSession 的方法实现的,SqlSession 封装了 Executor 的相关操作。以 select 为例,首先根据 SQL 语句关联的 statement 从 configuration 中获取 MappedStatement 对象,然后调用 Executor 的 query 方法执行查询操作。statement 的格式是命名空间+ID,ID 即是 XML 中 select 标签的 id 属性。MappedStatement 对象存储了 XML 中的 SQL 配置,如 ParameterMap、ResultMap 等。

 

@Override
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      executor.query(ms, wrapCollection(parameter), rowBounds, handler);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
}

 

 默认情况下,使用 Executor 接口的 SimpleExecutor 实现。SimpleExecutor 继承了抽象类 BaseExecutor。BaseExecutor 实现了 Executor 接口的方法,实现了缓存机制,可以从缓存中直接返回查询结果,但更具体的数据库操作交给子类 SimpleExecutor 实现。在 SimpleExecutor  类中执行查询的 doQuery 方法如下所示。首先从 Configuration 中创建 StatementHandler 接口实例,默认使用 RoutingStatementHandler 实现。然后在 prepareStatement 方法中获取数据库连接、初始化 Statement、设置参数等。再调用 StatementHandler 的 query 方法,执行数据查询,查询结果交给 resultHandler 处理。最后关闭 Statement。

 

@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    Statement stmt = null;
    try {
      Configuration configuration = ms.getConfiguration();
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.<E>query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
}

 

在 RoutingStatementHandler 中会根据配置选择一个 StatementHandler 的实现用于进一步的数据处理,默认是 PreparedStatementHandler 类。在该类的 query 方法中会执行 Statement 数据查询请求,请求完成后调用 ResultSetHandler 对查询结果进行处理和封装。ResultSetHandler 接口定义了对返回结果集进行处理的方法,默认使用的实现类是 DefaultResultSetHandler,在 handleResultSets 方法中完成结果集到 Java Bean 的映射。

 

@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    return resultSetHandler.<E> handleResultSets(ps);
}

 

 

查询结果的缓存

MyBatis 支持对查询结果进行缓存,以减少数据库操作提高效率,默认情况下执行 insert、update、delete 等操作会清理缓存。执行查询操作前,首先创建 CacheKey 对象,根据 SQL 语句、id、offset、limit 和参数更新 CacheKey 对象,CacheKey 对象会记录这些数据并更新 hashcode、checksum、count 几个整数,这些数据都用于判断 CacheKey 对象是否相等。

 

public void update(Object object) {
    int baseHashCode = object == null ? 1 : ArrayUtil.hashCode(object); 
    count++;
    checksum += baseHashCode;
    baseHashCode *= count;
    hashcode = multiplier * hashcode + baseHashCode;
    updateList.add(object);
}

  

select 语句的查询结果以 Map 形式存放在 PerpetualCache 类中,Map 的 key 是 CacheKey 对象,Map 的 value 是查询结果。

 

更新数据的流程

DefaultSqlSession 的 insert、delete 操作都是复用 update 操作实现的,update 的操作流程与 select 类似,不做过多阐述。所不同的是,执行 update 操作前需要先清理缓存,在 update 操作完成以后,还需要返回受影响的行数和 KeyGenerator 配置的自增值。

 

事务提交与回滚

DefaultSqlSession 的 commit 和 rollback 操作都是在 BaseExecutor 中实现的,先清除缓存,然后清理 Statement,如果有需要再调用 Transaction 的相关方法。如果要求强制执行,或者不自动提交且有脏数据,就会执行 Transaction 的 commit 或 rollback 操作。

 

每周 3 篇学习笔记或技术总结,面向有一定基础的 Java 程序员,内容涉及 Java 进阶、虚拟机、MySQL、NoSQL、分布式计算、开源框架等多个领域。关注作者或微信公众号 backend-develop 第一时间获取最新内容。

MyBatis 原理浅析 3 ——数据操作

分享到:
评论

相关推荐

    MyBatis3用户指导——简体中文版

    MyBatis3用户指导——简体中文版.

    MyBatis的逆向工程——generatorSqlmapCustom (2)

    在本篇文章中,我们将深入探讨MyBatis的逆向工程工具——generatorSqlmapCustom,这是对数据库模式进行自动生成代码的强大功能。在第一部分中,我们可能已经介绍了基础概念,现在我们将继续深入研究这一主题。 逆向...

    Spring+SpringMVC+Mybatis框架整合例子——亲测可用.zip

    Mybatis是一个优秀的持久层框架,它简化了JDBC的繁琐操作,支持SQL语句的动态编写,使得开发者可以直接使用SQL来操作数据库,同时还能保持数据访问的灵活性。Mybatis通过XML或注解方式配置映射文件,将Java对象与...

    MyBatis的逆向工程——generatorSqlmapCustom

    MyBatis的逆向工程,也称为代码生成器或者Generator,是MyBatis框架提供的一种自动化工具,能够帮助开发者快速生成基于数据库表的Java实体类、Mapper接口与XML配置文件等,大大提高了开发效率。在本项目...

    Spring整合Mybatis与SpringBoot整合Mybatis原理分析

    **Spring整合Mybatis原理分析** 在Java Web开发中,Spring框架以其强大的依赖注入和面向切面编程能力,成为了事实上的核心框架。Mybatis则是一个轻量级的持久层框架,它简化了数据库操作,提供了直观的SQL映射。将...

    【java框架】SpringBoot(7) -- SpringBoot整合MyBatis(csdn)————程序..pdf

    在SpringBoot中,可以通过`application.yaml`或`application.properties`文件配置数据源和MyBatis的相关信息。例如,我们可以指定Mapper接口的扫描路径以及全局配置文件的位置: ```yaml # application.yaml spring...

    mybatis中操作json类型数据(csdn)————程序.pdf

    在MyBatis中,操作JSON类型数据涉及到对MySQL数据库中JSON字段类型的映射和转换,以便于在Java代码中能够方便地处理这些数据。这里,我们主要关注如何自定义TypeHandler来实现这一功能。 首先,MySQL引入了JSON类型...

    深入浅出MyBatis技术原理与实战

    MyBatis的核心组件——SqlSessionFactory和SqlSession,是理解MyBatis工作原理的关键,书中将详尽阐述它们的作用和使用方法。 MyBatis的Mapper接口和XML配置文件是实现SQL与Java对象映射的主要手段。书中会深入探讨...

    【MyBatis入门】—— MyBatis日志

    这篇博客“【MyBatis入门】—— MyBatis日志”旨在帮助初学者理解如何在MyBatis中配置和使用日志功能,以便于调试和优化应用程序。 在MyBatis中,日志系统对于跟踪SQL语句和参数,以及检查执行效率至关重要。...

    mybatis原理.xmind

    该思维导图主要是对MyBatis原理知识进行了整理,通过对底层的分析,能够实现手写一个实现核心功能的简单MyBats,内容包括MyBatis整体架构和流程的分析、SQL的解析过程、手写解析流程、手写执行流程、看源码、MyBatis...

    Mybatis 学习笔记——原生DAO实现数据增删改查SQL

    Mybatis 学习笔记——原生DAO实现数据增删改查SQL:https://blog.csdn.net/qq_24598601/article/details/83037252

    【MyBatis学习笔记一】——MyBatis入门demo.zip

    【MyBatis学习笔记一】——MyBatis入门demo.zip 博客地址:https://blog.csdn.net/weixin_43817709/article/details/117370755

    深入理解mybatis原理

    在深入理解MyBatis原理的过程中,首先要探讨其架构设计,包括框架设计、数据处理层的功能以及框架支撑层中的事务管理机制。 MyBatis的设计理念是简单而优雅,它允许开发者通过Java编程来操作数据库,而不必像传统...

    【MyBatis学习笔记五】——MyBatis注解的简单使用.zip

    【MyBatis学习笔记五】——MyBatis注解的简单使用.zip 博客地址:https://blog.csdn.net/weixin_43817709/article/details/117407621

    【MyBatis入门】—— 第一个MyBatis应用

    【MyBatis入门】—— 第一个MyBatis应用 MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解...

    Spring3 整合MyBatis3 配置多数据源动态选择SqlSessionFactory详细教程

    Spring3 整合 MyBatis3 配置多数据源动态选择 SqlSessionFactory 详细教程 本教程主要介绍了 Spring3 整合 MyBatis3 配置多数据源动态选择 SqlSessionFactory 的详细教程。下面将详细介绍如何实现 Spring 整合 ...

    Mybatis拦截器记录数据更新历史记录到MongoDB

    首先,我们来理解Mybatis拦截器的原理。Mybatis的拦截器是基于Java的动态代理机制实现的,它允许我们在特定的执行点(如SQL语句的执行前、后或结果返回前)插入自定义的行为。这在很多场景下都非常有用,比如日志...

    深入浅出 mybatis技术原理与实践pdf

    首先,书中详细介绍了 MyBatis 的安装和配置过程,包括如何创建数据库连接、配置数据源、设置 MyBatis 配置文件等基础操作。这对于初学者来说是非常重要的起点,因为只有正确配置好环境,才能进行后续的开发工作。 ...

    【MyBatis学习笔记四】——MyBatis分页.zip

    MyBatis是一款优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。在实际开发中,数据量较大的时候,分页查询是非常重要的功能,能够有效地提高系统的性能和用户体验。本篇笔记主要围绕MyBatis如何实现...

    Mybatis入门实例(五)——MyBatis与Spring 3.X的整合

    在本教程中,我们将深入探讨如何将MyBatis与Spring 3.x进行集成,以便在实际项目中实现灵活且高效的数据库操作。MyBatis是一个优秀的持久层框架,它简化了SQL映射,而Spring框架则提供了强大的依赖注入和管理功能。...

Global site tag (gtag.js) - Google Analytics