MyBatis框架中sql语句的执行过程

  • Post author:
  • Post category:其他


一:概述



主要思路:dom4j解析配置文件生成一个全局配置对象,利用jdk动态代理创建出接口的代理类,通过代理类完成crud的操作,从而间接完成接口方法中的crud操作(代理通过以接口方法名为id就可以拿到对应的sql语句,所以dao接口的接口方法其中一个作用就是代理类用来寻找对应的sql语句的)

二:MyBatis使用的标准步骤

//通过流的方式加载mybatis配置文件
InputStream in = Resource.getResourseAsStream("classpath:mybatis.xml")

//创建sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in)

//创建sqlSession
SqlSession session = sqlSessionFactory.openSession()

//创建代理类
xxxDao dao = session.getMapper(xxxDao.class)

//执行语句
dao.selectXXX()

三:使用原始jdbc的标准步骤

//加载驱动
Class.forName("com.mysql.jdbc.Driver")

//建立连接
Connection connection = DriverManager.getConnection(url,userName,password);

//定义sql语句
String sql = "";

//创建语句对象
Statement statement = connection.PreparedStatement(sql);

//参数设置
statement.setXXX(index,vlaue)

//执行sql语句
ResultSet resultSet = statement.executeQuery()

//解析结果数据集
while(resultSet.hasNext()){
...
...
}
//关闭连接
statement.close();
connection.close();

四:MyBatis的底层就是JDBC

众所周知,MyBatis的底层就是jdbc,正所谓哪有什么幸福和平,只是有人在负重前行。MyBatis是如何帮我们完成底层的jdbc的操作的呢?在这里先简单概括一下

JDBC MyBatis
加载驱动 直接加载到JVM,与JDBC加载一样
创建连接 执行器创建
创建语句对象 配置文件中的语句会被封装成语句对象
参数设置 参数处理器执行
执行 执行器执行
处理返回集 返回值处理器处理



顺便提一下:MyBatis拥有四大对象,分别是执行器executor,语句控制器statementHandler,参数控制器parameterHandler以及返回值处理器resultSetHandler,该框架正是利用这四大对象来完成sql语句的执行与返回。

五:mybatis启动并执行一条语句的详细过程


1.解析MybatisConfig.xml,并封装成一个全局的Configuration对象,通过该对象来保存配置文件中的值

(1)实现逻辑:通过工具类Resource获取配置文件的输入流,然后利用SqlSessionFactoryBuilder解析xml文件生成的Configuration对象并以此为参数创建出SqlSessionFactory

(2)代码示例:

①  利用SqlSessionFactoryBuilder的build方法解析全局配置文件

②  利用build()里的parse方法进行解析

③利用parse里的parseConfiguration解析成configuration对象

④解析每一个标签结点(以mapper为例)

⑤  进入到this.mapperElement()方法,最后其实就是解析完该单个标签的值后给this.configuration赋值,最终返回该configuration(这里也完成了接口方法与mapper文件中的sql语句的绑定(MappedStatement对象))


2.SqlSessionFactory创建出SqlSession(默认是defaultSqlSession)


3.SqlSession创建出对应接口的代理类(接口式编程)

(1)实现逻辑:Mybatis启动时会创建出以接口类型为key,MapperProcyFactory为Value的knownMappers,通过knownMappers就可以找到接口的MapperProxyFactory,进而创建出代理类的实例对象,而MapperProxyFactory的实例对象MapperProxy则是InvocationHandler接口实现类并实现了invoke方法(实际就是用反射创建了代理类)

(2)代码示例

①通过sqlSession的getMapper()创建出对应的代理类

② 实际调用的是Configuration的getMapper方法,从mapper注册中心拿到对应的mapperProxyFactory,进而创建出MapperPeoxy实例

③:创建出MapperProxy实例并返回


4.调用dao层方法:MapperProxy的invoke方法中会执行已经被映射的sql方法

(1)实现逻辑:找到被绑定的sql语句,然后参数转换,参数设置等,然后利用执行器创建连接,创建语句对象,然后执行sql语句

(2)代码示例

①:MapperProxy的invoke方法

②:最终是调用内部类PlainMethodInvoker的invoke方法,进而调用mapperMethod的execute方法

③:execute方法,就是利用判断语句类型,通过sqlSession去执行底层的数据库CRUD操作,并通过返回值处理器等进行返回值处理


5.最后利用返回值处理器处理ResultSetHandler把查询结果处理,最后层层返回

最后:附上后端技术交流圈,欢迎各位大佬入圈交流…….(先添加好友后拉群,添加好友时请备注:小白不黑)



版权声明:本文为m0_57713282原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。