Mybatis源码总结

mybatis

Mybatis是一个orm框架,帮助我们更好的在java中编写和管理SQL语句
主要的运行过程:

  1. 主配置文件,配置mapper文件的位置,以及数据源,缓存,插件等配置信息,项目运行起来后会解析该文件,相关信息存储在Configuration对象中
  2. mapper文件,写sql,与mapper接口对应起来,实现sql和java代码分离,通过解析,会保存在Configuration对象中,key:全路径类名+方法名 ,value:MappedStatement对象,里面包含该方法sql的各种信息,二级缓存在该对象中
  3. sqlSession是主要的类,用来执行sql的增删改查,要生成它需要一个SqlSessionFactory工厂类,生产出来的sqlSession实现类DefaultSqlSession,其中一级缓存就是在这个类中
  4. sqlSession执行增删改查操作;也可以通过获取Mapper接口,通过接口来进行sql方法调用,获取到的Mapper接口是通过jdk的动态代理生成代理对象完成的,主要的动态代理逻辑在MapperProxy类中,然后通过调用sqlSession的增删改查方法进行sql执行。
  5. 下面介绍sqlSession的实现类DefaultSqlSession的select方法过程涉及到的重要类以及过程
    1. Executor:SqlSessionFactory的openSession在创建Executor的时候会把插件对应的拦截了该类中的方法进行动态代理,完成增强,该执行器的作用是生成sql语句(**MappedStatement 中的语句生成工具 **通过xml中写的sql是否有需要填充属性的分为动态sql和原始sql),以及一二级缓存的获取和更新,在这里通过Transaction获取数据库连接
    2. StatementHandler:也可以通过插件 进行拦截的方法,会创建ResultSetHandlerParameterHandler然后通过connection创建生成jdbc的PreparedStatement,然后调用parameterHandler填充参数
    3. ParameterHandler:使用paredStatement的setxxxx方法填充参数,在填充的时候要知道要填充的数据类型对应sql的数据类型,好调用对应的paredStatement的setxxx方法,这个时候需要TypeHandler的各种类型的实现,来调用paredStatement.setxxx方法
    4. 最后执行paredStatement.execute(sql)
    5. ResultSetHandler:处理执行后返回的jdbc的ResultSet,这里也需要TypeHandler处理数据库类型和java类型对应起来,调用对应的实现类的方法,设置给对应的java对象的属性

mybatis-spring

mapper对象注入IOC容器

  1. 通过**@MapperScan**注解导入MapperScannerRegistrar(实现ImportBeanDefinitionRegistrar)->MapperScannerConfigurer(实现的BeanDefinitionRegistryPostProcessor)->**ClassPathMapperScanner#doScan**要扫描所有的mapper接口,beandefinition改成MapperFactoryBean的class,设置MapperFactoryBean的各种属性,比如:当前mapper接口的的全路径类名,SqlSessionTemplate对象
  2. MapperFactoryBean:这是实现了FactoryBean接口,getObject中通过sqlSession#getMapper获取到对应Mapper的动态代理后的对象, 每个Mapper接口都有一个MapperFactoryBean

sqlSessionTemplate:

  1. 里面通过动态代理SqlSessionInterceptor,修改获取SqlSession的逻辑,主要是为了同一个事务线程中可以共用sqlSession,存储在threadLocal中。同时注入几个事务状态感知钩子类(通过TransactionSynchronizationManager.registerSynchronization())
  2. 真正干活的sqlSession还是通过SqlSessionFactory生成DeFaultSqlSession

mybatis-spring和spring事务

在mybatis中,负责事务处理的接口是Transaction(里面设置数据源);主要功能用来获取连接,事务提交和回滚

mybatis和spring整合后不会连接获取和进行提交事务,统一交给spring jdbc中的事务处理。
通过实现了mybatis中Transaction接口的SpringManagedTransaction类,该类中的获取连接又调用spring-jdbc中的工具获取,同时通过isConnectionTransactional属性控制不能再该类中进行提交和回滚,统一把这些回滚和提交工作交给spring事务框架。

spring事务处理大致流程:

  1. 通过TransactionInterceptor拦截器拦截目标方法
  2. 通过DataSourceTransactionManager获取事务,主要获取数据库连接资源并绑定到当前线程中的(TransactionSynchronizationManager),以及参数设置,read only参数会执行sql.
  3. 存储当前事务信息到TransactionInfo.oldTransactionInfo中,事务传播的时候需要
  4. 执行mapper的方法。MapperProxy代理(mybatis-plus中是MybatisMapperProxy); sqlSession是SqlSessionTemplate->SqlSessionInterceptor(动态代理,会通过sqlsession工厂获取sqlSession,并且作为资源绑定到当前线程中,所以同一个事务中可以使用一级缓存
  5. 提交或者回滚事务
    1. 提交事务
      1. triggerBeforeCommit :触发TransactionSynchronization#beforeCommit, 重要实现:mybatis-spring整合中有个SqlSessionUtils.SqlSessionSynchronization.beforeCommit,会执行sqlSession的commit,并不会在这里提交事务(因为事务管理使用了SpringManagedTransaction),只是刷掉sqlSession的缓存等
      2. triggerBeforeCompletion:触发触发TransactionSynchronization#beforeCompletion ,重要实现:mybatis-spring整合中有个SqlSessionUtils.SqlSessionSynchronization.beforeCompletion,会执行sqlSession.close方法,关闭sqlSession
      3. 传播级别嵌套事务的时候,子事务执行的时候,如果有回滚点,释放掉回滚点
      4. 事务执行提交操作,connection.commit()
      5. TransactionSynchronization.afterCommit
      6. 释放资源,数据库连接资源

TransactionSynchronizationManager:管理线程中的事务状态,以及事务资源在线程中的绑定,比如:数据库连接
ResourceHolderSupport:事务中的资源通过该基类,他实现了通过计数方式看当前是否释放资源 ,比如:ConnectionHolder,SqlSessionHolder
TransactionSynchronization: 可以实现钩子函数,在事务执行各个状态可以感知到

事务挂起:就是保留现有的连接,参数信息,等资源,用对象保存起来。然后清空当前线程的资源,重新获取连接

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值