1. Spring Boot 自动配置 Mybatis

1. Spring Boot 自动配置 Mybatis

自动配置

约定大于配置,缺省的配置看这个注解 @EnableConfigurationProperties({MybatisProperties.class})。这个注解中引入了MybatisProperties类,包含了一些默认的配置。

@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {}

MybatisAutoConfiguration的主要属性有:

  1. MybatisProperties:yaml文件中的属性配置
  2. Interceptor[] :拦截器数组
  3. TypeHandler[] :类型解析器等

构造方法:

  1. 从 yaml 文件中获取 mybatis 前缀的属性封装成对象​MybatisProperties​,赋值给 properties 。
  2. 获取拦截器
  3. 获取typeHandlers
  4. 其他。。。
创建 sqlSessionFactory

前提:

  1. 依赖DataSource 数据源 @ConditionalOnSingleCandidate(DataSource.class)。要求 BeanFactory 中存在指定类并且可以确定单个候选项才会匹配成功
  2. 在数据源完成自动配置之后配置 sqlSessionFactory = new SqlSessionFactoryBean().getObject();

正文:

  1. 创建一个工厂bean:​MybatisSqlSessionFactoryBean​​

  2. 工厂 bean 设置数据源dataSource。依赖注入,此时容器中已经有了dataSource,直接拿来用。

  3. 初始化配置属性

    1. 如果有配置 mybatis-config.xml 则设置configLocation 属性。
    2. 应用yaml 文件中嵌套配置 configuration到 factoryBean。
    3. TypeHandler
    4. 拦截器
  4. 通过工厂Bean的getObject方法获取sqlSessionFactory。

    1. 如果配置项 mapperLocation不为空,循环解析每一个 mapper.xml文件

    2. XMLMapperBuilder.parse() 解析xml 文件

      1. configurationElement​解析mapper 节点

        1.  <mapper namespace="com.pansnow.changcheng.mapper.UserMapper"><select id="queryUserList" resultType="com.pansnow.changcheng.pojo.User">select *from user</select><insert id="addUser" parameterType="com.pansnow.changcheng.pojo.User">insert into user(id, name, pwd)values (#{id}, #{name}, #{pwd});</insert><update id="updateUser" parameterType="com.pansnow.changcheng.pojo.User">update userset name=#{name},pwd=#{pwd}where id = #{id};</update><delete id="deleteUser" parameterType="int">deletefrom userwhere id = #{id};</delete></mapper>
          
        2. namespace判空。namespace 为 mapper 接口类的 String 字符串
        3. 解析 parameterMap 和 resultMap节点
        4. 解析 sql节点
        5. 解析 select|insert|update|delete
        6. 将该文件添加到已解析集合中。protected final Set<String> loadedResources;
        7. 将 mapper 类添加到 mapper注册表中,解析 mapper 类上的注解@Select、@SelectProvider、@ResultSet 等。
        8. 解析方法上的 SQL语句parseStatement。
创建sqlSessionTemplate
  1. 使用 jdk 动态代理,创建SqlSessionProxy,增强逻辑为SqlSessionInterceptor​。代理了SqlSession的创建和获取、事务、关闭。即在调用SqlSession接口中的每一个方法时,都会调用SqlSessionInteceptor的invoke逻辑。

  2. SqlSessionInterceptor​的逻辑为:

    1. 创建SqlSession。使用 selSessionFactory

      代理对象是如何获取defaultSqlSession ,在代理方法中通过SqlSessionUtils 的方法获取SqlSession

      • 它会首先获取SqlSessionHolder,SqlSessionHolder用于在TransactionSynchronizationManager中保持当前的SqlSession。
      • 如果holder不为空,并且holder被事务锁定,则可以通过holder.getSqlSession()方法,从当前事务中获取sqlSession,即 Fetched SqlSession from current transaction。
      • 如果不存在holder或没有被事务锁定,则会创建新的sqlSession,即 Creating a new SqlSession,通过sessionFactory.openSession()方法。
      • 如果当前线程的事务是活跃的,将会为SqlSession注册事务同步,即 Registering transaction synchronization for SqlSession。
      SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
      
      1. 如果 session 为 null,

        1. 利用事务工厂创建一个事务,
        2. 新建一个 Executor:这个是干嘛的,不太清楚哇。
        3. 新建一个 DefaultSqlSession。
        4. 创建sqlSessionHolder 将 sqlSession 包起来。
        5. 将sqlSessionHolder存放到TransactionSynchronizationManager​的synchronizations​中。synchronizations​是一个 set 集合。
    2. 调用业务方法

    3. 如果有事务,提交事务

    4. 关闭 session。关闭前会释放 holder。​holder.released();

      SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
      
创建MapperScannerRegistrarNotFoundConfiguration

主要在于根据配置创建MapperScannerConfigurer​,

@Import({AutoConfiguredMapperScannerRegistrar.class}) 这个AutoConfiguredMapperScannerRegistrar类非常关键,因为他在扫描@Mapper 注解

  1. BeanDefinitionBuilder​:创建MapperScannerConfigurer​的 BeanDefinitionBuilder
  2. 设置扫描注解类:Mapper.class
  3. 设置扫描包路径
  4. 设置sqlSessionFactoryBeaName
  5. 设置 sqlSessionTemplateBeanName
  6. 注册MapperScannerConfigurer​到注册表中
MapperScannerConfigurer

实现了 BeanDefinitionRegistryPostProcessor ,工作在bean 定义的注册阶段。

扫描@Mapper 注解,为什么需要单独处理呢?因为 Mapper 注解是 mybatis 自定义注解,和 Component 注解没有关系。这个类会将@Mapper 注解下的类也实例化后放入到 Spring 容器中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/594418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ消息队列常见面试题

前言 本文是对RabbitMQ的常见面试题问答的总结&#xff0c;同时也是一个RabbitMQ的入门学习&#xff0c;还没了解的同学快来认识一下。 1.RabbitMQ消息模型有哪些&#xff1f; &#xff08;1&#xff09;HelloWorld 模型(点对点模型) 一个生产者一个消息队列一个消费者 &a…

三种 SqlSession

三种 SqlSession ​SqlSession​ 是一个接口&#xff0c;并且里面包含了许多 CRUD 操作数据库等方法。 ​SqlSession​​ 它有三个实现类&#xff0c;分别是 SqlSessionManager​​ 、DefaultSqlSession​​ 和 SqlSessionTemplate​​&#xff0c;其中 DefaultSqlSession​​…

使用函数的选择法排序

本题要求实现一个用选择法对整数数组进行简单排序的函数。 函数接口定义&#xff1a; void sort( int a[], int n ); 其中a是待排序的数组&#xff0c;n是数组a中元素的个数。该函数用选择法将数组a中的元素按升序排列&#xff0c;结果仍然在数组a中。 裁判测试程序样例&am…

15、Kubernetes核心技术 - 探针

目录 一、概述 二、探针类型 2.1、就绪探针&#xff08;Readiness Probe&#xff09; 2.2、存活探针&#xff08;Liveness Probe&#xff09; 三、探针探测方法 3.1、exec 3.2、httpGet 3.3、tcpSocket 四、探针配置项 五、探针使用 5.1、就绪探针&#xff08;Readin…

自定义异常面试及答案(2024)

1、为什么要使用自定义异常&#xff1f; 使用自定义异常&#xff08;Custom Exceptions&#xff09;在程序设计中是一个良好的实践&#xff0c;它有几个重要的好处&#xff1a; 提高代码可读性&#xff1a; 自定义异常的名称如果能清晰表达出异常的情况&#xff0c;那么阅读代…

springboot整合ftp服务器实现上传与下载

springboot整合ftp服务器实现上传与下载 1. 添加依赖 在项目的pom.xml文件中添加spring-boot-starter-web和commons-net的依赖&#xff1a; <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…

Java框架相关高频面试题

一&#xff0c;Spring 1&#xff0c;Spring框架中单例bean是线程安全的吗&#xff1f; 2&#xff0c;什么是AOP&#xff1f;你项目有用过吗&#xff1f; 3&#xff0c;Spring事务的失效场景有哪些&#xff1f; 发生自身调用&#xff08;类中使用this调用本类的方法&#xff0…

全国计算机等级考试| 二级Python | 真题及解析(9)

一、选择题 1. 以下关于程序设计语言的描述,错误的选项是: A Python语言是一种脚本编程语言 B汇编语言是直接操作计算机硬件的编程语言 C程序设计语言经历了机器语言、汇编语言、脚本语言三个阶段 D编译和解释的区别是一次性翻译程序还是每次执行时都要翻译程序 正确答…

java每日一题——找出区间内的素数(答案及编程思路)

前言&#xff1a; 学习编程还是要做大量练习呀&#xff0c;不能只学不练&#xff0c;一个题目可以从多个角度去解决&#xff0c;可以全方面巩固知识点。每天记录一点点&#xff0c;daydayup&#xff01; 题目&#xff1a;判断101-200之间有多少个素数&#xff0c;并输出所有素数…

这货能大大增强ChatGpt的战斗力

今天我给你介绍一个能大大增强ChatGpt的战斗力的工具&#xff1a; gapier。 注册gapier ChatGpt推出了GPTs的功能&#xff0c;在创建GPTs的时候有个Actions的选项&#xff0c;是给我们调用第三方接口用的&#xff0c;以前一直不知道这么用。 直到我发现了一个网站&#xff1a…

11.盛水最多的容器(双指针,C解法)

题目描述&#xff1a; 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;…

FX3U-1PG使用

作为扩展模块的安装 伺服驱动器的参数设置 1.设置为0&#xff0c;为位置模式&#xff0c;发送脉冲控制&#xff1b; 2. 设置旋转方向&#xff0c;以及脉冲方式&#xff0c;通常设置为01&#xff0c;因为FX3U-1PG只支持正方向脉冲负方向脉冲方式&#xff1b; 当然想改变电机运…

图灵完备 / 图灵机 / 状态转移

图灵完备 "图灵完备"是计算理论中的一个概念&#xff0c;指的是一种计算系统或编程语言具有足够的能力来模拟图灵机&#xff08;Turing machine&#xff09;。 艾伦图灵提出了图灵机的概念&#xff0c;这是一种理论计算机模型&#xff0c;可以执行算法。图灵完备性…

PostgreSQL学习笔记01

RDS RDS是Relational Database Service&#xff08;关系型数据库服务&#xff09;的简称&#xff0c;它是亚马逊AWS提供的一种托管式关系型数据库服务。RDS旨在简化数据库的设置、运维和扩展&#xff0c;使开发人员可以专注于应用程序的开发&#xff0c;而不必关注基础设施的管…

docker如何配置阿里云镜像加速?

登录阿里云后&#xff0c;我们点击右上角的控制台&#xff0c;控制台中搜索镜像加速服务&#xff0c;然后点击帮助文档的官方镜像加速&#xff1a; 点击容器镜像服务控制台&#xff1a; 在镜像工具里面的镜像加速器中就可以看到&#xff1a; 分别执行即可&#xff1a; 之后我们…

Python调用C++/C

#include<iostream> extern "C" {int foo(int a, int b) {std::cout << "a b " << a b << std::endl;return a b;} } 如果是编译C代码&#xff0c;需要写上 extern "c" 生成动态文件&#xff1a;g -shared -o tes…

Docker与虚拟机的比对

在Windows操作系统上的对比&#xff1a; 但是官方还是建议我们尽量不要将Docker直接安装到Windows操作系统上。

k8s---声明式资源管理(yml文件)

在k8s当中支持两种声明资源的方式&#xff1a; 1、 yaml格式&#xff1a;主要用于和管理资源对象 2、 json格式&#xff1a;主要用于在API接口之间进行消息传递 声明式管理方法(yaml)文件 1、 适合对资源的修改操作 2、 声明式管理依赖于yaml文件&#xff0c;所有的内容都在y…

5大自动化测试的Python框架,看完就能涨薪5k 【实用干货】

目前&#xff0c;它在Tiobe指数中排名第三个&#xff0c;仅次于Java和C。随着该编程语言的广泛使用&#xff0c;基于Python的自动化测试框架也应运而生&#xff0c;且不断发展与丰富。 因此&#xff0c;开发与测试人员在为手头的项目选择测试框架时&#xff0c;需要考虑许多方…

微服务(12)

目录 56.k8s是怎么进行服务注册的&#xff1f; 57.k8s集群外流量怎么访问Pod&#xff1f; 58.k8s数据持久化的方式有哪些&#xff1f; 59.Relica Set和Replication Controller之间有什么区别&#xff1f; 60.什么是Service Mesh&#xff08;服务网格&#xff09;&#x…