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

MyBatis 原理浅析——基本原理

 
阅读更多

前言

MyBatis 是一个被广泛应用的持久化框架。一个简单的使用示例如下所示,先创建会话工厂,然后从会话工厂中打开会话,通过 class 类型和配置生成 Mapper 接口的代理实现,最后使用 Mapper 进行持久化操作。

 

本文将从 MyBatis 中的 SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession 和 Mapper 几个方面入手简单分析 MyBatis 的实现原理。在后面的系列文章中会进一步具体分析核心类的细节实现。

 

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 使用 Builder 模式去生成 SqlSessionFactory,因此只提供了多个 build 方法。这些方法可以接受 XML 配置文件的 Reader 或 InputStream 输入流,也可以传入 environment 指定环境或传入 Properties 作为属性。

 

在 build 方法的实现中,首先根据传入的输入流、environment 和 Properties 构建 XMLConfigBuilder 对象,然后调用其 parse() 方法解析 XML 文件得到 Configuration 对象,最后创建 SqlSessionFactory 对象并返回。

 

SqlSessionFactory

SqlSessionFactory 是一个工厂接口,默认实现是 DefaultSqlSessionFactory。SqlSessionFactory 的作用是获取 SqlSession,因此提供了多个 openSession 方法,支持从 DataSource 数据源和一个给定的连接 Connection 中创建 SqlSession。

 

openSession 方法的底层实现可以分为 5 步:

①从 Configuration 对象中获取环境配置 Environment;

②根据环境配置得到事务工厂 TransactionFactory;

③从事务工厂得到事务 Transaction,Transaction 包装了数据库连接,处理数据库连接的创建、准备、提交、回滚和关闭;

④创建执行器 Executor;

⑤创建 SqlSession,返回 DefaultSqlSession 的实例。

其中从 DataSource 数据源创建 SqlSession 的过程如下所示:

    Transaction tx =null;
    try{
    finalEnvironment environment = configuration.getEnvironment();
    finalTransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
    finalExecutor executor = configuration.newExecutor(tx, execType);
    returnnewDefaultSqlSession(configuration, executor, autoCommit);
    }catch(Exception e){
    closeTransaction(tx);// may have fetched a connection so lets call close()
    throwExceptionFactory.wrapException("Error opening session. Cause: "+ e, e);
    }finally{
    ErrorContext.instance().reset();
    }

 

 

SqlSession

SqlSession 是一个接口,默认实现是 DefaultSqlSession,提供了多种数据库操作方式,如 select、selectOne、selectList、insert、update、delete、commit、rollback 和 getMapper 等方法。getMapper 方法用于获取 Mapper 接口的代理实现。在 MyBatis 中建议使用 Mapper 接口操作数据库。

 

数据库的增删改查和事务的提交回滚都是通过 Executor 执行的。Executor 有 3 种类型 SIMPLE、REUSE、BATCH,默认使用简易执行器 SIMPLE,REUSE 类型执行器重用预处理语句,BATCH 类型执行器重用预处理语句和批量更新。Executor 对象的创建在 Configuration 类型的 newExecutor 方法中进行。

 

Executor 在执行过程中,会用到 StatementHandler、ParameterHandler 和 ResultHandler,其中 StatementHandler 封装了 java.sql.Statement 的相关操作,ParameterHandler 封装了 SQL 对参数的处理,ResultHandler 封装了对返回数据集的处理。Executor 的执行过程,就是对这 3 个对象的调度过程。更多分析在后续文章中进行。

 

Mapper

Mapper 是通过 JDK 动态代理实现的,在 MapperProxyFactory 中创建 MapperProxy 并进行接口代理封装。对 Mapper 接口的调用实际上是由 MapperProxy 实现的。

 

    @SuppressWarnings("unchecked")
    protected T newInstance(MapperProxy<T> mapperProxy){
    return(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{ mapperInterface }, mapperProxy);
    }
     
    public T newInstance(SqlSession sqlSession){
    finalMapperProxy<T> mapperProxy =newMapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
    }

 

 

在 MapperProxy 中,实现了 InvocationHandler 的 invoke 方法。methodCache 是一个 ConcurrentHashMap,其中存储了方法与 MapperMethod 的对应关系。从 methodCache 缓存中获取或创建 MapperMethod 对象,然后调用 MapperMethod 对象的 execute 方法执行数据库操作。

 

    @Override
    publicObject invoke(Object proxy,Method method,Object[] args)throwsThrowable{
    try{
    if(Object.class.equals(method.getDeclaringClass())){
    return method.invoke(this, args);
    }elseif(isDefaultMethod(method)){
    return invokeDefaultMethod(proxy, method, args);
    }
    }catch(Throwable t){
    throwExceptionUtil.unwrapThrowable(t);
    }
    finalMapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
    }
     
    privateMapperMethod cachedMapperMethod(Method method){
    MapperMethod mapperMethod = methodCache.get(method);
    if(mapperMethod ==null){
    mapperMethod =newMapperMethod(mapperInterface, method, sqlSession.getConfiguration());
    methodCache.put(method, mapperMethod);
    }
    return mapperMethod;
    }

 

 

创建 MapperMethod 对象时,会在构造函数中初始化 SqlCommand 和MethodSignature。SqlCommand 包含了数据库操作的名称,格式为 “接口名.操作名称”,以及 XML 中配置的操作类型,如 select、update等,把一个 Mapper 接口与 XML中的一个配置结合起来。MethodSignature 是方法的签名,标记了方法的返回值类型,对于使用 RowBounds(offset 和 limit 配置)、ResultHandler(结果处理回调)作为参数的方法记录参数位置并初始化参数处理器。

 

在 MapperMethod 的 execute 方法中,根据 SqlCommand 中的配置选择 SqlSession 的方法,根据 MethodSignature 的配置处理传入的参数,调用 SqlSession 的方法进行数据库操作,最后根据 MethodSignature 的返回值类型返回操作结果。

 

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

MyBatis 原理浅析--基本原理
0
0
分享到:
评论

相关推荐

    【MyBatis入门】—— MyBatis日志

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

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

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

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

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

    MyBatis学习总结——MyBatis快速入门.docx

    下面我们将深入探讨MyBatis的基本概念和实现步骤。 1. **项目创建与依赖** - 创建一个Java项目或JavaWeb项目作为起点。 - 添加MyBatis的核心库`mybatis-3.1.1.jar`以及MySQL驱动包`mysql-connector-java-5.1.7-...

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

    1. **Spring整合Mybatis的基本步骤** - **引入依赖**: 在项目的pom.xml中添加Spring和Mybatis的相关依赖。 - **配置数据源**: 配置数据库连接信息,如JDBC驱动、URL、用户名和密码。 - **配置Mybatis**: 创建...

    Mybatis自学教程——入门篇demo

    Mybatis是一款优秀的Java持久层框架,它支持定制化SQL、存储过程以及高级映射。本教程将引导你逐步了解并掌握Mybatis的基础知识,让你在Java开发中更加游刃有余地处理数据库操作。 首先,我们需要理解Mybatis的核心...

    mybatis原理.xmind

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

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

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

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

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

    阿里巴巴P7架构师纯手工打造MyBatis源码——1小时解密底层源码.txt

    ### MyBatis源码解析——由阿里巴巴P7架构师纯手工打造 #### 一、前言 在现代软件开发过程中,持久层框架如MyBatis因其简单易用、灵活高效的特点而受到广泛欢迎。作为一款优秀的Java持久层框架,MyBatis通过SQL...

    《深入浅出MyBatis技术原理与实战》高清完整PDF下载

    接着介绍了MyBatis的运行原理和插件开发并配有一个完整的插件例子。为了增加实用性,作者还介绍了MyBatis-Spring项目,使得读者能够学习到如何把MyBatis整合到Spring项目中,最后作者还将讲解一些常用实例,比如Blob...

    深入浅出MyBatis技术原理与实战(高清带目录版)

    《深入浅出MyBatis技术原理与实战》分为3 个部分,依次介绍了MyBatis 的基础应用、原理及插件开发、实践应用,使读者能够由浅入深、循序渐进地掌握MyBatis 技术。首先,《深入浅出MyBatis技术原理与实战》在官方API ...

    深入理解mybatis原理

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

    第一个mybatis程序——CRUD

    首先,我们需要理解MyBatis的基本架构。MyBatis通过XML或注解方式配置映射文件,将SQL语句与Java代码分离,使得开发更为简洁,同时避免了JDBC代码的繁琐。下面我们将按照步骤进行: 1. **环境准备**:确保你的开发...

    Mybatis实例——可直接导入eclipse运行

    Mybatis 是一款流行的Java持久层框架,它实现了SQL映射框架,使得开发者可以直接编写...在实际开发中,你还可以根据需求扩展这些基本配置,例如添加更多的Mapper接口,处理更复杂的业务逻辑,或者优化数据库连接池等。

    springmvc+mybatis原理分析

    springmvc+mybatis原理分析

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

     《深入浅出MyBatis技术原理与实战》分为3个部分,依次介绍了MyBatis的基础应用、原理及插件开发、实践应用,使读者能够由浅入深、循序渐进地掌握MyBatis技术。首先,《深入浅出MyBatis技术原理与实战》在官方API的...

    MyBatis的逆向工程——generatorSqlmapCustom

    首先,我们需要了解MyBatis Generator(MBG)的基本使用。MBG通过读取配置文件,根据配置中的数据库连接信息、表名和指定的规则,自动生成相应的Java源代码。配置文件通常为XML格式,其中包含了数据库连接信息、目标...

Global site tag (gtag.js) - Google Analytics