手写mybatis彻底搞懂框架原理(mybatis原理)

2025-09-28 20:30:01 0

手写mybatis彻底搞懂框架原理(mybatis原理)

大家好,关于手写mybatis彻底搞懂框架原理很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于mybatis原理的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

本文目录

mybatis原理

MyBatis 的工作原理:读取 MyBatis 配置文件、加载映射文件、构造会话工厂、创建会话对象、Executor 执行器、输入参数映射、输出结果映射。

mybatis原理具体介绍如下:

1、读取 MyBatis 配置文件:


mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。

2、加载映射文件:


映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3、构造会话工厂:

通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4、创建会话对象:

由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5、Executor 执行器:


MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6、MappedStatement 对象:


在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7、输入参数映射:


输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8、输出结果映射:


输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

ssm框架原理及流程是什么

SSM全称是Spring+SpringMVC+MyBatis。

SSM框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的web项目的框架。

1、Spring

Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。

2、SpringMVC

SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责。

3、mybatis

mybatis是对jdbc的封装,它让数据库底层操作变的透明。

SSM框架集是软件架构的一个部分。以下是软件架构的种类:

1、逻辑架构

软件系统系统当中的各个元件之间所存在的关系,比如外部系统接口、用户界面、商业逻辑元件、数据库等。

2、物理架构

究竟是怎样做到在硬件当中放置软件元件。例如处于上海与北京进行分布的分布式系统的物理架构,这也就是说全部的元件都是属于物理设备,主要的有主机、整合服务器、应用服务器、代理服务器、存储服务器、报表服务器、Web服务器、网络分流器等。

mybatis原理是什么

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。

用xml文件构建SqlSessionFactory实例是非常简单的事情。推荐在这个配置中使用类路径资源(classpath resource),但你可以使用任何Reader实例,包括用文件路径或file://开头的url创建的实例。MyBatis有一个实用类----Resources,它有很多方法,可以方便地从类路径及其它位置加载资源。

把Mybatis的功能架构分为三层:

1、API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

2、数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

3、基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

Spring整合Mybatis一文讲透,手把手带你实操

在介绍Spring整合Mybatis原理之前,我们得先来稍微介绍Mybatis的工作原理。

在Mybatis中,我们可以使用一个接口去定义要执行sql,简化代码如下: 定义一个接口,@Select表示要执行查询sql语句。

以下为执行sql代码:

Mybatis的目的是:使得程序员能够以调用方法的方式执行某个指定的sql,将执行sql的底层逻辑进行了封装。 这里重点思考以下mapper这个对象,当调用SqlSession的getMapper方法时,会对传入的接口生成一个 代理对象,而程序要真正用到的就是这个代理对象,在调用代理对象的方法时,Mybatis会取出该方法所对应的sql语句,然后利用JDBC去执行sql语句,最终得到结果。

UserService中的userMapper属性就会被自动注入为Mybatis中的代理对象。如果你基于一个已经完成整合的项目去调试即可发现,userMapper的类型为: org.apache.ibatis.binding.MapperProxy@41a0aa7d。证明确实是Mybatis中的代理对象。 好,那么现在我们要解决的问题的就是:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中?要解决这个,我们需要对Spring的bean生成过程有一个了解。

Spring启动过程中,大致会经过如下步骤去生成bean

假设有一个A类,假设有如下代码: 一个A类

一个B类,不存在@Component注解

执行如下代码:

输出结果为:com.luban.util.A@6acdbdf5 A类对应的bean对象类型仍然为A类。但是这个结论是不确定的,我们可以利用BeanFactory后置处理器来 修改BeanDefinition,我们添加一个BeanFactory后置处理器:

这样就会导致,原本的A类对应的BeanDefiniton被修改了,被修改成了B类,那么后续正常生成的bean对 象的类型就是B类。此时,调用如下代码会报错:

但是调用如下代码不会报错,尽管B类上没有@Component注解:

并且,下面代码返回的结果是:com.luban.util.B@4b1c1ea0

之所以讲这个问题,是想说明 个问题:在Spring中,bean对象跟class没有直接关系,跟 BeanDefinition才有直接关系。 那么回到我们要解决的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中? 在Spring中,如果你想生成一个bean,那么得先生成一个BeanDefinition,就像你想new一个对象实 例,得先有一个class。

继续回到我们的问题,我们现在想自己生成一个bean,那么得先生成一个BeanDefinition,只要有了 BeanDefinition,通过在BeanDefinition中设置bean对象的类型,然后把BeanDefinition添加给 Spring,Spring就会根据BeanDefinition 动帮我们 成 个类型对应的bean对象。 所以,现在我们要解决两个问题:

注意:上文中我们使用的BeanFactory后置处理器,他只能修改BeanDefinition,并不能新增一个 BeanDefinition。我们应该使用Import技术来添加一个BeanDefinition。后面再详细介绍如果使用Import 技术来添加一个BeanDefinition,可以先看一下伪代码实现思路。

假设:我们有一个UserMapper接口,他的代理对象的类型为UserMapperProxy。 那么我们的思路就是这样的,伪代码如下:

但是,这里有一个严重的问题,就是上文中的UserMapperProxy是我们假设的,他表示一个代理类的类 型,然而Mybatis中的代理对象是利用的JDK的动态代理技术实现的,也就是代理对象的代理类是动态生成的,我们根本方法确定代理对象的代理类到底是什么。 所以回到我们的问题:Mybatis的代理对象的类型是什么? 本来可以有两个答案: 1. 代理对象对应的代理类 2. 代理对象对应的接口 那么答案1就相当于没有了,因为是代理类是动态生成的,那么我们来看答案2:代理对象对应的接口如果我们采用答案2,那么我们的思路就是:

但是,实际上给BeanDefinition对应的类型设置为一个接口是行不通的,因为Spring没有办法根据这个 BeanDefinition去new出对应类型的实例,接口是没法直接new出实例的。 那么现在问题来了,我要解决的问题:Mybatis的代理对象的类型是什么? 两个答案都被我们否定了,所以这个问题是无解的,所以我们不能再沿着这个思路去思考了,只能回到最 开始的问题:如何能够把Mybatis的代理对象作为一个bean放入Spring容器中?

总结上文的推理:我们想通过设置BeanDefinition的class类型,然后由Spring自动的帮助我们去生成对应的bean,但是这条路是行不通的。 终极解决方案 那么我们还有没有其他办法,可以去生成bean呢?并且生成bean的逻辑不能由Spring来帮我们做了,得 由我们自己来做。 FactoryBean 有,那就是Spring中的FactoryBean。我们可以利用FactoryBean去自定义我们要生成的bean对象,比如

我们定义了一个LubanFactoryBean,它实现了FactoryBean,getObject方法就是用来自定义生成bean 对象逻辑的。 执行如下代码:

将打印: lubanFactoryBean: com.luban.util.LubanFactoryBean 1@4d41cee &lubanFactoryBean: com.luban.util.LubanFactoryBean@3712b94 lubanFactoryBean-class: class com.sun.proxy. Proxy20 从结果我们可以看到,从Spring容器中拿名字为"lubanFactoryBean"的bean对象,就是我们所自定义的 jdk动态代理所生成的代理对象。

所以,我们可以通过FactoryBean来向Spring容器中添加一个自定义的bean对象。上文中所定义的 LubanFactoryBean对应的就是UserMapper,表示我们定义了一个LubanFactoryBean,相当于把 UserMapper对应的代理对象作为一个bean放入到了容器中。 但是作为程序员,我们不可能每定义了一个Mapper,还得去定义一个LubanFactoryBean,这是很麻烦的 事情,我们改造一下LubanFactoryBean,让他变得更通用,比如:

改造LubanFactoryBean之后,LubanFactoryBean变得灵活了,可以在构造LubanFactoryBean时,通 过构造传入不同的Mapper接口。 实际上LubanFactoryBean也是一个Bean,我们也可以通过生成一个BeanDefinition来生成一个 LubanFactoryBean,并给构造方法的参数设置不同的值,比如伪代码如下:

特别说一下注意二,表示表示当前BeanDefinition在生成bean对象时,会通过调用LubanFactoryBean的 构造方法来生成,并传入UserMapper的Class对象。那么在生成LubanFactoryBean时就会生成一个 UserMapper接口对应的代理对象作为bean了。 到此为止,其实就完成了我们要解决的问题:把Mybatis中的代理对象作为一个bean放入Spring容器中。

只是我们这是用简单的JDK代理对象模拟的Mybatis中的代理对象,如果有时间,我们完全可以调 Mybatis中提供的方法区生成一个代理对象。这里就不花时间去介绍了。 Import 到这里,我们还有一个事情没有做,就是怎么真正的定义一个BeanDefinition,并把它添加到Spring中, 上文说到我们要利用Import技术,比如可以这么实现: 定义如下类:

并且在AppConfig上添加@Import注解:

这样在启动Spring时就会新增一个BeanDefinition,该BeanDefinition会生成一个LubanFactoryBean对 象,并且在生成LubanFactoryBean对象时会传入UserMapper.class对象,通过LubanFactoryBean内部 的逻辑,相当于会自动生产一个UserMapper接口的代理对象作为一个bean。

总结一下,通过我们的分析,我们要整合Spring和Mybatis,需要我们做的事情如下:


作者:程序员周瑜
***隐藏网址***

Mybatis源码解析(1) 如何获得SQL语句

笔者只能说会使用Mybtis,并没有具体研究过源码,站在一个使用者的角度记录解决的问题。
跳过大部分源码,从一个功能点开始入手。

以 Select 操作为例,研究如何获取经过 Mybatis 中 动态语句 转换后的的 SQL语句
我们这里不涉及复杂的过程原理(如:读取配置文件、Mapper代理等( 我也不懂 )),只说明一下具体流程。

发现studentMapper被MapperProxy实现。

好奇的同学肯定会问studentMapper是如何创建MapperProxy实例的呢?

一路跟随瞎点。会发现一个配置类,里面东西很多,目前只看和Mapper有关系。

我们继续下一步

到此关于Mapper的运行过程已经分析完了,下面继续分析SelectOne过程。

selectOne 其实只是 selectList 取第一个元素(这点是没有想到的)。

源码解析,这还是第一次写这类文章,确实这些框架的原理,并没有研究过只是知道一点概念,Mapper动态代理之类的。网上的博客从大方向出发,框架设计、设计模式之类的,对于我这种基础薄弱的人看的云里雾里。我准备从一个一个功能开始初步了解、研究此类框架原理。
***隐藏网址***

怎么学习java中的一个框架

框架是程序员们必学的知识点,而且是十分重要的应用,Spring、SpringMVC、Mybatis也是经典中的经典,最常用的框架类型。

作为Java新手应该如何去学习框架呢?搜集了很多网友的建议,现在为大家总结如下:

有同学建议:对于Spring来说,最应该学习的就是Spring的IOC原理,这在使用过程中是必须要理解的、必会的。用配置文件或者是Annonation的方式来代替New创建实例,可以说这是一个历史性的进步,并且前进了一大步,影响深远。也是间接的促成了接口实现分离的优雅风格。

另外,该同学还认为,建议把Hibernate换成Mybatis。

还有更接地气的同学建议说:从配置文件开始,理解三个字母各自是如何工作的,以及是如何协同工作的。我从零开始学ssm的时候就这么干的,花了一个月左右,使用起来就比较熟练了。然后深入框架的一些高级用法。再接着琢磨它们的原理、思想和设计、实现。最后到能自己重新发明轮子。

更有给力的同学给出了详细的建议,连具体步骤都给出了明确的说明。具体如下:

  • java语法基础,可以看think in java;

  • servlet,jsp,jdbc,结合html,css,js实现自己想要的小网站,功能慢慢积少成多;

  • spring,springmvc,springdata,hibernate,mybatis等框架学习,一上来用这些框架忽略基础,这样会出现只会用xxx框架,换个yyy框架又得重新学习的感觉;

  • 设计模式,aop,oop等的学习,当然可以和之前的步骤反复来研究提高。

  • 对于具体的操作,很多有经验的小伙伴也有妙招:其实不外乎实操这一真理,就是亲自去写一些框架,实践出真知,只有实际操作过了才能真正理解那些曾经学过的知识都是怎么回事。

    比如这位朋友建议写一些通过JDBC直接到数据库读写数据的代码,写一个简单的web app,可以登记用户,要对数据有效性能控制,要能检测错误。然后再想办法优化成spring, mybatis和springmvc。优化到代码越少越好。

    实操之后最重要的就是思考,每做完一个项目就做一次总结,动脑多想想为什么、接下来怎么做,那么框架那点事儿就不叫事儿了。

    下面把我收藏的Java框架教程分享给大家,绝对值得参考!

    1. SSM框架:spring+SpringMVC+MyBatis

    强烈推荐!全网最全SSM框架集教程,Spring+SpringMVC+MyBatis一套搞定! Spring整合MyBatis项目开发;SpringMVC框架部署和配置,SprinGMVC框架全流程执行原理 ;ybatis配置和使用、Mybatis常见面试问题解析。

    SSM框架教程(附源码)Spring+SpringMVC+MyBatis入门一套搞定!

    2. Spring全套详解(Ioc-AOP-整合MyBatis)

    包括Spring IoC、Spring AOP(CGLib、JDK动态代理)、Spring整合MyBatis,Spring事务管理等内容。

    Spring从入门到精通全套教程_通俗易懂进阶必看(Ioc-AOP-整合MyBatis)

    3. Mybatis框架(全程带练,源码解析)

    包括ORM概述、Mybatis概述、Mybatis增删查改、Mybatis配置文件详解、Mybatis关联映射、MyBatis动态SQL、Mybatis日志配置、Mybatis连接池、Mybatis缓存、Mybatis延迟加载、Mybatis原理解析等。

    Mybatis框架视频教程,mybatis(idea版)实战教程(全程带练,源码解析)

    4. SpringMVC(框架源码解析)

    包括SpringMVC的框架部署配置、创建控制器、前端请求控制器或者静态资源配置、控制器接收前端数据、并对前端请求作出响应等全流程全细节的讲解。最后将会完成三大框架(Spring、SpringMVC、Mybatis)终极整合。

    一套快速掌握spring mvc(框架源码解析)

    5. 持久层开发框架-MybatisPLUS

    MybatisPlus教程(深入浅出,快速上手),Mybatis-Plus带你高效开发WEB应用。

    MybatisPlus教程(深入浅出,快速上手)

    6. 服务快速开发技术-springboot

    课程提供了配套的所有资料,领取方法见评论区置顶。本套视频基于官方提供的最新版本SpringBoot 2.7.1进行讲解,不仅课程内容全网最新,内容也非常全面,覆盖机构及企业针对于springBoot所有的内容需求,课程一共分为4个章节,课程围绕着核心基础、日志框架、SpringBoot与其他技术整合(如Redis Ecache Elasticsearch MQ Quarts....)等、源码的剖析(搭建源码环境、运行的原理、内置tomcat、自定义starter等等)还有部署监控等内容。

    SpringBoot2全套,springboot快速入门到项目实战视频教程

    7.Spring Security

    本套课程首先带来大家学会Spring Security框架的基本用法,手把手教大家完成框架的基本配置。然后详细讲解Security框架中的过滤器、认证方式、JWT的使用等内容。最后使用Spring Security+JWT的方式,做一个权限认证系统的微服务项目。从单体环境下的权限认证,到微服务前后端分离式的权限系统,实现对整个课程内容的升级。

    SpringSecurity最新框架教程,从基础入门到Spring Security+JWT微服务项目实战

    8.Java日志框架

    本套课程是针对有Java基础的小伙伴进行讲解,由浅入深详细讲解每个知识点以及编程思想,系统完整的帮助小伙伴建立完备的Java日志系统知识体系以及高性能的日志框架选型。

    Java日志框架教程,由浅入深全面精讲多种日志框架(log4j、slf4j、logback、jul、juc、springboot )

    9. 微服务框架-Spring cloud

    通过学习你将深刻理解微服务架构, 精通springcloud-alibaba各个组件的工作原理及其使用,吊打面试官,高薪拿offer。

    SpringCloud框架入门到精通全套教程 java微服务架构基础 史上最简单全面的微服务开发教程

    10. 分布式框架-Dubbo

    旨在深度分析服务之间调用逻辑,从剖析RPC底层原理开始,通过手写RPC框架,掌握RPC实现逻辑。通过全方位介绍微服务RPC框架Dubbo,实现Dubbo在各实战场景中的应用。通过剖析Dubbo源码,掌握Dubbo的服务通信、负载均衡、SPI机制及服务治理的实现逻辑。

    RPC+Dubbo框架入门最全教程_dubbo源码实战

    11. 分布式框架-zookeeper

    通过学习你将具备: Zookeeper的底层数据存储逻辑 Zookeeper客户端的完整操作流程 Zookeeper集群实战技能 分布式架构思维的引导及建立。

    Zookeeper集群教程-全网最全Zookeeper应用及原理分析课程

    以上就是为大家总结的关于学习Java框架的一些技巧和方法,尤其对于初学者最为重要。

    还是那句话,学得再多不如一次实操,边学边练是永远不变的真理,也只有这样才能真正的学到东西,才能真正的把知识转化为技能从而转化为自己的财富。

彻底搞懂JDBC的运行过程

前几天笔者发布了博客,手写mybatis彻底搞懂框架原理。为了帮助初学者更好理解mybatis框架,这次讲解一下Java的JDBC的运行过程。

JDBC的作用

JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。JDBC接口及相关类在java.sql包和javax.sql包里。我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。

JDBC接口让Java程序和JDBC驱动实现了松耦合,使得切换不同的数据库变得更加简单。

JDBC的连接步骤

执行一次JDBC连接,分六个步骤进行:

1. 导入包

在程序中包含数据库编程所需的JDBC类。大多数情况下,使用 import java.sql.* 就足够了

2. 注册JDBC驱动程序

需要初始化驱动程序,这样就可以打开与数据库的通信。

3. 打开一个连接

使用DriverManager.getConnection()方法来创建一个Connection对象,它代表一个数据库的物理连接。

4. 执行一个查询

需要使用一个类型为Statement或PreparedStatement的对象(两者区别看后文),并提交一个SQL语句到数据库执行查询。

5. 从结果集中提取数据

这一步中演示如何从数据库中获取查询结果的数据。使用ResultSet.getXXX()方法来检索的数据结果

6. 清理环境资源

在使用JDBC与数据交互操作数据库中的数据后,应该明确地关闭所有的数据库资源以减少资源的浪费。本文使用了try with resources方式关闭资源,这是JDK7的语法糖,读者可自行搜索。

完整代码如下。

JDBC的最佳实践

JDBC是如何实现Java程序和JDBC驱动的松耦合?

JDBC API使用Java的反射机制来实现Java程序和JDBC驱动的松耦合。看一下上文的JDBC示例,你会发现所有操作都是通过JDBC接口完成的,而驱动只有在通过Class.forName反射机制来加载的时候才会出现。

这是Java核心库里反射机制的最佳实践之一,它使得应用程序和驱动程序之间进行了隔离,让迁移数据库的工作变得更简单。

Statement和PreparedStatement区别

预编译

创建时的区别:

执行时的区别:

由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少次,都不会再去进行编译,而Statement 不同,如果执行多次,则相应的就要编译多少次sql,所以从这点看,PreparedStatement的效率会比Statement要高一些。PreparedStatement是预编译的,所以可以有效的防止SQL注入等问题

占位符

PrepareStatement可以替换变量在SQL语句中可以包含?,可以用?替换成变量。

而Statement只能用字符串拼接。

JDBC的ResultSet

在查询数据库后会返回一个ResultSet,它就像是查询结果集的一张数据表。

ResultSet对象维护了一个游标,指向当前的数据行。开始的时候这个游标指向的是第一行。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了,next()方法会返回false。可以在for循环中用它来遍历数据集。

默认的ResultSet是不能更新的,游标也只能往下移。也就是说你只能从第一行到最后一行遍历一遍。不过也可以创建可以回滚或者可更新的ResultSet,像下面这样。

当生成ResultSet的Statement对象要关闭或者重新执行或是获取下一个ResultSet的时候,ResultSet对象也会自动关闭。

可以通过ResultSet的getter方法,传入列名或者从1开始的序号来获取列数据。

ResultSet的不同类型

根据创建Statement时输入参数的不同,会对应不同类型的ResultSet。如果你看下Connection的方法,你会发现createStatement和prepareStatement方法重载了,以支持不同的ResultSet和并发类型。

ResultSet对象有三种类型。

ResultSet有两种并发类型。

Mybatis Mapper接口是如何找到实现类的-源码分析

KeyWords: Mybatis 原理,源码,Mybatis Mapper 接口实现类,代理模式,动态代理,Java动态代理,Proxy.newProxyInstance,Mapper 映射,Mapper 实现

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。我们在使用 Mybaits 进行 ,通常只需要定义几个 Mapper 接口,然后在编写一个 xml 文件,我们在配置文件中写好 sql , Mybatis 帮我们完成 Mapper 接口道具体实现的调用。以及将结果映射到 model bean 中。

我们在项目中所编写的众多的 Mapper 类只是一个接口(interface ),根据 Java 的多态性我们知道,可以使用接口接口作为形参,进而在运行时确定具体实现的对象是什么。但是,对于 Mapper 接口,我们并没有编写其实现类!Mybatis是如何找到其实现类,进而完成具体的 CRUD 方法调用的呢?原理何在?

为了弄清楚 Mapper 接口是如何找到实现类的,我们先回忆一下 Mybatis 是怎么使用的,根据实际的例子,进而一点点的去分析。这里的使用指的是Mybatis 单独使用,而不是整合 spring , 因为整合 spring 的话,还需要涉及 Mapper dao 装载到 spring 容器的问题,spring 帮忙创建数据源配置等问题。

通常我们使用 Mybatis 的主要步骤是:

从一段代码看起

上面我们概括了使用 Mybatis 的4个步骤。这4个步骤看起来很简单,但是用代码写出来就很多。我们不妨先记着这4个步骤,再去看代码,会容易点。

在这块代码中,第 1 部分我们使用了 Java 编码的形式来实现 SqlSessionFactory ,也可以使用 xml 。如果使用xml的话,上面的第一部分代码就是这样的:

我们本次的目标是弄清楚 “ Mapper 是如何找到实现类的 ”,我们注意上面代码 3 , 4 的位置:

这里 mapper 可以调用selectBlog(1) 这个方法,说明 mapper 是个对象,因为对象才具有方法行为实现啊。BlogMapper接口是不能实例化的,更没有具体方法实现。我们并没有定义一个类,让它实现BlogMapper接口,而在这里它只是通过调用session.getMapper() 所得到的。由此,我们可以推断:肯定是session.getMapper() 方法内部产生了BlogMapper的实现类。有什么技术可以根据BlogMapper 接口生成了一个实现类呢?想到这里,对于有动态代理 使用经验的程序员来说,很容易想到,这背后肯定是基于动态代理技术,具体怎么实现的呢?下面我们来根据源码一探究竟。

Mapper 接口的注册

从上面的代码中,我们知道 BlogMapper 接口的实现类是从session.getMapper中得来的,大概是基于动态代理技术实现。我们既然能够从SqlSession中得到BlogMapper接口的,那么我们肯定需要先在哪里把它放进去了,然后 SqlSession 才能生成我们想要的代理类啊。上面代码中有这么一行:

跟着这个 addMapper 方法的代码实现是这样的:

我们看到这里 mapper 实际上被添加到 mapperRegissry 中。继续跟进代码:

看到这里我们知道上面所执行的configuration.addMapper(BlogMapper.class); 其实最终被放到了HashMap中,其名为knownMappers ,knowMappers是MapperRegistry 类的一个私有属性,它是一个HashMap 。其Key 为当前Class对象,value 为一个MapperProxyFactory 实例。

这里我们总结一下: 诸如BlogMapper 之类的Mapper接口被添加到了MapperRegistry 中的一个HashMap中。并以 Mapper 接口的 Class 对象作为 Key , 以一个携带Mapper接口作为属性的MapperProxyFactory 实例作为value 。MapperProxyFacory从名字来看,好像是一个工厂,用来创建Mapper Proxy的工厂。我们继续往下看。

Mapper接口的动态代理类的生成

上面我们已经知道,Mapper 接口被到注册到了MapperRegistry中——放在其名为knowMappers 的HashMap属性中,我们在调用Mapper接口的方法的时候,是这样的:

这里,我们跟踪一下session.getMapper() 方法的代码实现,这里 SqlSession 是一个接口,他有两个实现类,一个是DefaultSqlSession,另外一个是SqlSessionManager,这里我们用的是DefaultSqlSession. 为什么是DefaultSqlSession呢?因为我们在初始化SqlSessionFactory的时候所调用的SqlSessionFactoryBuilder的build()方法里边配置的就是DefaultSqlSession, 所以,我们进入到DefaultSession类中,看看它对session.getMapper(BlogMapper.class)是怎么实现的:

如代码所示,这里的 getMapper 调用了 configuration.getMapper , 这一步操作其实最终是调用了MapperRegistry,而此前我们已经知道,MapperRegistry是存放了一个HashMap的,我们继续跟踪进去看看,那么这里的get,肯定是从这个hashMap中取数据。我们来看看代码:

我们调用的session.getMapper(BlogMapper.class);最终会到达上面这个方法,这个方法,根据BlogMapper的class对象,以它为key在knowMappers 中找到了对应的value —— MapperProxyFactory(BlogMapper) 对象,然后调用这个对象的newInstance()方法。根据这个名字,我们就能猜到这个方法是创建了一个对象,代码是这样的:

看到这里,就清楚了,最终是通过Proxy.newProxyInstance产生了一个BlogMapper的代理对象。Mybatis 为了完成 Mapper 接口的实现,运用了代理模式。具体是使用了JDK动态代理,这个Proxy.newProxyInstance方法生成代理类的三个要素是:

代理模式中,代理类(MapperProxy)中才真正的完成了方法调用的逻辑。我们贴出MapperProxy的代码,如下:

我们调用的 Blog blog = mapper.selectBlog(1); 实际上最后是会调用这个MapperProxy的invoke方法。这段代码中,if 语句先判断,我们想要调用的方法是否来自Object类,这里的意思就是,如果我们调用toString()方法,那么是不需要做代理增强的,直接还调用原来的method.invoke()就行了。只有调用selectBlog()之类的方法的时候,才执行增强的调用——即mapperMethod.execute(sqlSession, args);这一句代码逻辑。

而mapperMethod.execute(sqlSession, args);这句最终就会执行增删改查了,代码如下:

再往下一层,就是执行JDBC那一套了,获取链接,执行,得到ResultSet,解析ResultSet映射成JavaBean。

至此,我们已经摸清楚了Blog blog = mapper.selectBlog(1); 中,BlogMapper接口调用到得到数据库数据过程中,Mybaitis 是如何为接口生成实现类的,以及在哪里出发了最终的CRUD调用。实际上,如果我们在调用Blog blog = mapper.selectBlog(1);之前,把从slqSession中得到的 mapper 对象打印出来就会看到,输出大概是这样的:

动态代理没错吧,Java动态代理实在是太美妙了。

上面我们用层层深入的方式摸清楚了 Mapper接口是如何找到实现类的。我们分析了 Mapper接口是如何注册的,Mapper接口是如何产生动态代理对象的,Maper接口方法最终是如何执行的。总结起来主要就是这几个点:

java如何构建一个简单的mybatis框架

一、Mybatis介绍
MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果。MyBatis能够使用简单的XML格式或者注解进行来配置,能够映射基本数据元素、Map接口和POJOs(普通java对 象)到数据库中的记录。
二、MyBatis工作流程
(1)加载配置并初始化
触发条件:加载配置文件
配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求 触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。
orm工具的基本思想
无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点:
从配置文件(通常是XML配置文件中)得到 sessionfactory.
由sessionfactory 产生 session
在session 中完成对数据的增删改查和事务提交等.
在用完之后关闭session 。
在java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。
功能架构
Java框架篇---Mybatis 入门
Mybatis的功能架构分为三层:
API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
多需要添加的驱动包:
Java框架篇---Mybatis 入门
下面进行快速入门:
目录如下:
Java框架篇---Mybatis 入门
实体类User
package com.oumyye.model;
public class User {
private String id;
private String name;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User ";
}
}
映射文件UserMapping.xml
《?xml version="1.0" encoding="UTF-8" ?》
***隐藏网址***
《mapper namespace="com.oumyye.mapping.UserMapping"》
《!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复
使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
resultType="com.oumyye.model.User"就表示将查询结果封装成一个User类的对象返回
User类就是users表所对应的实体类
--》
《!--
根据id查询得到一个user对象
--》
《select id="getUser" parameterType="String"
resultType="com.oumyye.model.User"》
select * from user where id=#{id}
《/select》
《/mapper》
资源文件mybatis.xml
《?xml version="1.0" encoding="UTF-8"?》
***隐藏网址***
《configuration》
《environments default="development"》
《environment id="development"》
《transactionManager type="JDBC" /》
《!-- 配置数据库连接信息 --》
《dataSource type="POOLED"》
《property name="driver" value="com.mysql.jdbc.Driver" /》
《property name="url" value="jdbc:mysql://localhost:3306/mybatis" /》
《property name="username" value="root" /》
《property name="password" value="root" /》
《/dataSource》
《/environment》
《/environments》
《mappers》
《mapper resource="com/oumyye/mapping/userMapping.xml"/》
《/mappers》
《/configuration》
测试类:
package test;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import com.oumyye.model.User;
public class Tests {
@Test
public void test(){
String resource = "mybatis.xml";
//使用类加载器加载mybatis的配置文件(它也加载关联的映射文件)
InputStream is = Tests.class.getClassLoader().getResourceAsStream(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = sessionFactory.openSession();
/**
* 映射sql的标识字符串,
* com.oumyye.mapping.UserMapping是userMapper.xml文件中mapper标签的namespace属性的值,
* getUser是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
*/
String statement = "com.oumyye.mapping.UserMapping.getUser";//映射sql的标识字符串
//执行查询返回一个唯一user对象的sql
User user = session.selectOne(statement, "1123");
System.out.println(user.toString());
}
}

mybatis原理的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于mybatis原理、mybatis原理的信息别忘了在本站进行查找哦。

手写mybatis彻底搞懂框架原理(mybatis原理)

本文编辑:admin

更多文章:


c程序设计实训教程第二版(C程序设计(第三版)与C程序设计(第二版)有什么区别都是谭浩强的那个)

c程序设计实训教程第二版(C程序设计(第三版)与C程序设计(第二版)有什么区别都是谭浩强的那个)

大家好,如果您还对c程序设计实训教程第二版不太了解,没有关系,今天就由本站为大家分享c程序设计实训教程第二版的知识,包括C程序设计(第三版)与C程序设计(第二版)有什么区别都是谭浩强的那个的问题都会给大家分析到,还望可以解决大家的问题,下面

2025年10月17日 06:00

phpstorm怎么保存(phpstorm 怎么设置自动上传)

phpstorm怎么保存(phpstorm 怎么设置自动上传)

本篇文章给大家谈谈phpstorm怎么保存,以及phpstorm 怎么设置自动上传对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录phpstorm 怎么设置自动上传phpstorm的sftp怎么记住密码phpstorm 怎么设

2025年12月11日 13:00

怎样用html制作一个简单的网页(怎样利用记事本和HTML制作一个简单的网页)

怎样用html制作一个简单的网页(怎样利用记事本和HTML制作一个简单的网页)

各位老铁们,大家好,今天由我来为大家分享怎样用html制作一个简单的网页,以及怎样利用记事本和HTML制作一个简单的网页的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面

2026年4月21日 01:15

无法打开360安全卫士(360安全卫士打不开怎么办为什么360安全卫士打不开)

无法打开360安全卫士(360安全卫士打不开怎么办为什么360安全卫士打不开)

大家好,无法打开360安全卫士相信很多的网友都不是很明白,包括360安全卫士打不开怎么办为什么360安全卫士打不开也是一样,不过没有关系,接下来就来为大家分享关于无法打开360安全卫士和360安全卫士打不开怎么办为什么360安全卫士打不开的

2026年8月20日 04:45

asp是编程语言吗(请问 asp 是不是一门编程语言)

asp是编程语言吗(请问 asp 是不是一门编程语言)

“asp是编程语言吗”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看asp是编程语言吗(请问 asp 是不是一门编程语言)!本文目录请问 asp 是不是一门编程语言什么是ASP 是不是JAVA HTML一样的编程语言as

2025年6月9日 18:00

美国img模特经纪公司(有谁知道国际有名的模特经纪公司有那些)

美国img模特经纪公司(有谁知道国际有名的模特经纪公司有那些)

本篇文章给大家谈谈美国img模特经纪公司,以及有谁知道国际有名的模特经纪公司有那些对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录有谁知道国际有名的模特经纪公司有那些美国和法国最大最好的国际模特公司叫什么啊 谢谢 谢谢世界十大

2026年8月7日 17:15

网页制作代码下载(网页制作代码下载)

网页制作代码下载(网页制作代码下载)

本篇文章给大家谈谈网页制作代码下载,以及网页制作代码下载对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录网页制作代码下载我想做一个网页供下载用,可是下载代码怎么写用VB快速下载[网页源代码]怎样下载网页代码网页制作代码下载**

2025年7月2日 02:15

plc编程书籍(PLC应用技术的图书信息1)

plc编程书籍(PLC应用技术的图书信息1)

大家好,今天小编来为大家解答以下的问题,关于plc编程书籍,PLC应用技术的图书信息1这个很多人还不知道,现在让我们一起来看看吧!本文目录PLC应用技术的图书信息1刚开始接触PLC,麻烦大家推荐PLC编程从入门到精通的书籍零基础学习PLC编

2026年9月16日 17:30

excel2010函数教案(excel函数培训教程步骤讲解)

excel2010函数教案(excel函数培训教程步骤讲解)

大家好,如果您还对excel2010函数教案不太了解,没有关系,今天就由本站为大家分享excel2010函数教案的知识,包括excel函数培训教程步骤讲解的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!本文目录excel函

2026年7月19日 04:45

数字时钟代码(如何使用JS实现一个简易数码时钟)

数字时钟代码(如何使用JS实现一个简易数码时钟)

大家好,数字时钟代码相信很多的网友都不是很明白,包括如何使用JS实现一个简易数码时钟也是一样,不过没有关系,接下来就来为大家分享关于数字时钟代码和如何使用JS实现一个简易数码时钟的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开

2026年2月6日 07:15

excel+e(excel数字显示e+怎么办)

excel+e(excel数字显示e+怎么办)

各位老铁们,大家好,今天由我来为大家分享excel+e,以及excel数字显示e+怎么办的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!本文目录excel数

2026年3月12日 17:45

烙铁头和眼镜王蛇哪个更有毒(中国最毒的蛇排名)

烙铁头和眼镜王蛇哪个更有毒(中国最毒的蛇排名)

本篇文章给大家谈谈烙铁头和眼镜王蛇哪个更有毒,以及中国最毒的蛇排名对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。本文目录中国最毒的蛇排名蟒山烙铁头

2026年1月31日 02:45

datagridview单元格值改变事件(C# 如何在dataGridView中直接修改单元格的值)

datagridview单元格值改变事件(C# 如何在dataGridView中直接修改单元格的值)

各位老铁们,大家好,今天由我来为大家分享datagridview单元格值改变事件,以及C# 如何在dataGridView中直接修改单元格的值的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动

2025年12月28日 05:45

安卓asynctask(安卓里异步加载怎么弄的)

安卓asynctask(安卓里异步加载怎么弄的)

“安卓asynctask”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看安卓asynctask(安卓里异步加载怎么弄的)!本文目录安卓里异步加载怎么弄的关于安卓启动界面的问题安卓的asyncTask 的execute是什么安

2025年7月10日 17:30

java字符串截取后两位(JAVA截取所有指定字符后面的字符串)

java字符串截取后两位(JAVA截取所有指定字符后面的字符串)

大家好,关于java字符串截取后两位很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于JAVA截取所有指定字符后面的字符串的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有

2025年12月5日 23:15

teaching形式(teach的V-s形式)

teaching形式(teach的V-s形式)

“teaching形式”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看teaching形式(teach的V-s形式)!本文目录teach的V-s形式teachⅰng什么意思句子中的teach为什么要用ing的形式teach的

2025年11月9日 19:30

datagrid控件模板(WPF怎么让datagrid的某个cell下的模板控比如textBox,获取焦点要光标一闪一闪的效果,便于用户输入)

datagrid控件模板(WPF怎么让datagrid的某个cell下的模板控比如textBox,获取焦点要光标一闪一闪的效果,便于用户输入)

这篇文章给大家聊聊关于datagrid控件模板,以及WPF怎么让datagrid的某个cell下的模板控比如textBox,获取焦点要光标一闪一闪的效果,便于用户输入对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。本文目录WPF怎么让

2026年1月16日 23:00

soap请求(soap协议和普通的post请求有什么区别呢)

soap请求(soap协议和普通的post请求有什么区别呢)

各位老铁们好,相信很多人对soap请求都不是特别的了解,因此呢,今天就来为大家分享下关于soap请求以及soap协议和普通的post请求有什么区别呢的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!本文目录soap协议和普

2026年5月6日 22:15

网页设计网页标签图标怎么做(如何给网站设置ICO图标)

网页设计网页标签图标怎么做(如何给网站设置ICO图标)

这篇文章给大家聊聊关于网页设计网页标签图标怎么做,以及如何给网站设置ICO图标对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。本文目录如何给网站设置ICO图标网页前面的小图标怎么弄如何在网页标题栏中插入图片图标如何制作网站logo如何

2025年12月6日 18:15

电脑上的cms(戴尔新系统找不到cms)

电脑上的cms(戴尔新系统找不到cms)

大家好,电脑上的cms相信很多的网友都不是很明白,包括戴尔新系统找不到cms也是一样,不过没有关系,接下来就来为大家分享关于电脑上的cms和戴尔新系统找不到cms的一些知识点,大家可以关注收藏,免得下次来找不到哦,下面我们开始吧!本文目录戴

2025年8月31日 11:15

近期文章

本站热文

electronics软件(labcenter electronics是什么软件)
2025-05-22 23:45:02 浏览:134
博客是微博吗(博客是微博吗)
2025-05-22 22:45:01 浏览:111
diversity and distribution(悬赏英语短文)
2025-05-23 16:15:02 浏览:107
ios软件开发前景(iOS就业前景怎么样)
2025-05-22 23:00:01 浏览:102
next month(有The next month这个单词吗,和 next month有什么区别)
2025-05-23 02:30:01 浏览:102
patron(patron是什么意思)
2025-05-23 10:30:02 浏览:95
标签列表

热门搜索