【MyBayis】MyBayis详解(2)MyBatis体系结构以及如何执行一条查询(SqlSessionFactory、SqlSession、Mapper)

一、SqlSessionFactory

简介:

  • SqlSessionFactory是MyBatis的关键对象,通过SqlSessionFactoryBuilder对象类获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例。
  • 所有MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心。
  • SqlSessionFactory是线程安全的,SqlSessionFactory一旦被创建应该在应用执行期间都存在。
  • SqlSessionFactory不要重复创建多次,建议使用单例模式。
  • SqlSessionFactory是创建SqlSession的工厂。

掌握以上概念后,我们从源码入手,了解整个SqlSessionFactory实现了什么共嫩,为什么是MyBatis的关键对象,如何加载一个Configuration对象以及如何创建一个SqlSession。

源码:
源码
从源码可见,SqlSessionFactory接口里有不同参数重载的open方法,以及一个获取Configuration对象的方法,包含参数作用如下:

参数名作用
autoCommit是否自动提交(默认false)
ConnectionJDBC中与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果
Transaction Isolation Level事务隔离级别(参考:https://www.cnblogs.com/xrq730/p/5087378.html)
ExecutorType执行器执行类型,有三种值,默认为simple(参考:https://blog.csdn.net/cleargreen/article/details/80614362)

Configuration:
Configuration对象包含数据源、事务、mapper文件资源以及影响数据库行为属性设置settings。

通过xml文件生成Configuration对象时所用到的重要标签如下:通过xml文件生成Configuration对象

二、SqlSession

简介:

  • SqlSession是MyBatis的关键对象,是执行持久化操作的独享,类似于JDBC中的Connection。
  • 它是应用程序与持久层之间执行交互操作的一个对象,也是MyBatis执行持久化操作的关键对象。
  • SqlSession对象完全包含以数据库为背景的所有执行SQL操作的方法,它的底层封装了JDBC连接,可以用SqlSession实例来直接执行被映射的SQL语句。
  • 每个线程都应该有它自己的SqlSession实例。
  • 使用完SqlSeesion之后关闭Session很重要,应该确保使用finally块来关闭它。

SqlSession四大对象:

  • Execute:调度执行StatementHandler、ParmmeterHandler、ResultHandler执行相应的SQL语句;
  • StatementHandler:使用数据库中Statement(PrepareStatement)执行操作,即底层是封装好了的prepareStatement;
  • ParammeterHandler:处理SQL参数;
  • ResultHandler:结果集ResultSet封装处理返回。

SqlSession如何执行一条查询?
从JDBC开始:
JDBC
MyBatis本质上是封装了JDBC的一个ORM框架,那么它肯定也有对应的流程用来解析、处理一条SQL语句。
根据源码,以:Blog blog = (Blog) session.selectOne(“org.mybatis.example.BlogMapper.selectBlog”, 101);
为例。
MyBatis
那么得出对应关系:
对应关系

三、Mapper接口

MyBatsi如何通过没有实现类的接口执行查询?
从代理模式说起:
代理模式
我们从之前的通过SqlSession查询可以知道,执行一个查询需要给select提供:nameSpace、ID、param以及Return,那么一个Mapper接口是如何得到这些参数的呢?
Mapper
最终方法会通过反射的方式调用MapperProxy中的invoke方法。
MapperProxy中的invoke
然后通过mapperMethod.execute(sqlSession, args);进行查询。
以mapperMethod的中的case select为例,方法最终返回结果还是调用了sqlSesion的select方法
在这里插入图片描述
那么代码是怎么一步一步走到MapperProxy中的invoke中的呢?
首先通过SqlSession.getMapper根据传入Mapper名称,调用Configuration中的mapperRegistry.getMapper,Configuration中维护了所有的mapper.xml解析出来的Mapper对象,然后调用MapperProxyFactory中的Proxy.newProxyInstance生成一个对应的代理实例,最终将数据转递到MapperProxy中的invoke进行查询。

四、总结

1、mybatis启动加载配置文件

  • MyBatis在初始化的时候,会将MyBatis的配置信息全部加载到内存中,使用org.apache.ibatis.session.Configuration实例来维护。使用者可以使用sqlSession.getConfiguration()方法来获取。

在这里插入图片描述

  • 此加载到内存中会生成一个对应的MappedStatement对象,然后会以key=”mapper接口路径”,value为MappedStatement对象的形式维护到Configuration的一个Map中。当以后需要使用的时候,只需要通过Id值来获取。

  • SqlSession的职能: SqlSession根据Statement ID, 在mybatis配置对象Configuration中获取到对应的MappedStatement对象,然后调用mybatis执行器来执行具体的操作。

2、开启一个数据库访问会话–创建sqlSession对象
在这里插入图片描述
MyBatis封装了对数据库的访问,把对数据库的会话和事务控制放到了SqlSession对象中。

3、利用sqlSession对象进行对话
以下使用一个selectList例子进行讲解:
在这里插入图片描述
4、MyBatis执行器Executor执行

  • 根据参数MappedStatement 、param,动态地生成需要执行的SQL语句,用BoundSql对象表示创建缓存

  • 根据参数,创建StatementHandler对象handler

  • 创建Statement对象,把StatementHandler必要参数赋值给Statement对象,使用Statement对象进行查询

  • StatementHandler.query(Statement, ResultHandler)

  • 处理返回结果,加工为想要的数据格式返回

    Executor的功能和作用:

    • 根据传递的参数,完成SQL语句的动态解析,生成BoundSql对象,供StatementHandler使用
    • 为查询创建缓存,以提高性能
    • 创建JDBC的Statement连接对象,进行操作

5、StatementHandler的作用
在这里插入图片描述
把必要参数赋值给Statement对象
在这里插入图片描述
处理结果集ResultSet,加工为想要返回的数据格式

6、MyBatis配置文件加载过程
过程

  • 调用SqlSessionFactoryBuilder对象的build(inputStream)方法;
  • SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfigBuilder对象;
  • SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法;
  • XMLConfigBuilder对象返回Configuration对象;
  • SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象;
  • SqlSessionFactoryBuilder返回 DefaultSessionFactory对象给Client,供Client使用。
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值