一次Mybatis部分源码阅读

Mybatis是ORM层的解决方案,其特性包括延迟加载,缓存等。既然是ORM层的解决方案,本质上当然是帮助我们更合理的去访问数据库,所以延迟加载和缓存打算以后再看,今天只阅读了部分源码,梳理一下Mybatis是如何帮助我们操作数据库的。

可以先梳理一下如果没有Mybatis,我们是怎么利用JDBC去访问数据库的,这么几个步骤:

1.Class.forName()加载驱动。这儿有个题外话,为什么这里的类加载用Class.forName()而不用类加载器是因为前者加载后可以进行初始化阶段,这是需要的,而后者不可以。

2.DriverManager.getConnection()获得连接connection。

3.connection.createStatement()创建statement。

4.statement.executeUpdate()/statement.executeQuery()执行SQL。

5.用ResultSet接受上一步的执行结果,在去遍历解析。

6.如果之前connection.setAutoCommit(false)设置了关闭自动提交事务,还要connection.commit()提交事务。

7.最后还要记得依次关闭resultset,statement,connection。

原始而又复杂,这个时候解决方案Mybatis就来了。

Mybatis引入了一个sqlSession的概念,这是一个接口。可以看看里面有哪些抽象方法。

调用这些方法是不是仿佛自己在用执行SQL操作数据库?居然还有事务。可以把它理解为Mybatis暴露给我们的操作数据库的入口,那怎么拿到它呢?有一个SqlSessionFactory,这是个接口,DefaultSqlSessionFactory实现了它,看类名也看出来了,利用了工厂模式,该类里面重载了很多opsession()方法去获得sqlsession。

怎么拿倒不是关键的,从我们利用Mybatis的编码中也可以看出来怎么拿。

重要的是拿之前当然要构建sqlsession了,既然是从sqlsessionFactory里面拿的,当然是要先构建sqlsessionFactory了,我们是通过SqlSessionFactoryBuilder去构建的,其build()方法源码如图:

这个build()方法可以分这么几步理解,构建sqlsessionFactory需要知道构建成什么样子的啊即要知道相关配置Configuration,那就是先构建Configuration对象了。

1.把配置文件里的相关配置读出来初始化好

2.知道相关配置了,那就去构建Configuration对象吧

3.既然有了Configuration那就去构建sqlsessionFactory吧

分开来详细梳理一下:

第一步:把配置文件里的相关配置读出来初始化好,即

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

这个初始化过程直接贴图:

 XMLConfiguration的构造需要三个参数,输入流inputStream/reader,String类型的environment和配置类Properties对象,XMLConfigBuilder会利用输入流和Properties对象构建了一个XPathParse对象,然后this()调用另一个构造方法,因为Configuration是其父类BaseBuilder的属性,在这个构造方法里,先super()初始化Configuration对象,再初始化其他属性,比如environment,值得注意的是把一个布尔型parsed设置为false,这个两个属性的作用后面会说。下面两张图是XPathParse对象的初始化过程:

到这里为止只是做了一个属性的初始化工作。核心还是下面的parse()方法。

第二步:知道相关配置了,那就去构建Configuration对象吧,即

parser.parse()

先贴parse()源码:

该方法的返回类型果然是Configuration,在这个方法里,刚搁置的那个布尔型parsed就有用了,它是用来控制这个XMLConfiguration只被使用一次,即parse()方法拿到Configuration对象只能被调用一次 。因为调用这个方法后parsed会被设置为true,就理解成调用过了嘛,parse()方法进来会有一个判断,使用过了?那就抛异常吧。然后是使用XPathParser对象的evalNode方法获取配置文件的里内容,就我们写在<configuration></configuration>里的东西。再然后就是核心了,在parseConfiguration()方法里分别给Configuration对象设置属性。这个方法里调用了这么多方法,其实这些方法最后都是各种configuration.set.../add...,可以注意一下其中一个mapperElement(),这个方法里就是可以让我们写的这么多SQL在mapper.XML生效,看一眼它的源码应该就可以理解了,各种name,url,resource,很熟悉吧。

到这里Configuration对象也拿到了。接下来就是最后一步了。

第三步:既然有了Configuration那就去构建sqlsessionFactory吧,即

var5 = this.build(parser.parse());

先看这个build()里是什么:

嗷~,原来是构建了一个 DefaultSqlSessionFactory,那就去看看吧:

 这个DefaultSqlSessionFactory实现了SqlSessionFactory,看来到头了,源码读到这里,上诉三步梳理完了,已经知道SqlSessionFactory怎么来的了。我们在编码中会利用SqlSessionFactory的openSession()拿到sqlSession去操作数据库,那就继续看sqlSession怎么来的吧。

知道相关配置的DefaultSqlSessionFactory是怎么通过一系列的opsession方法去构建sqlsession的呢?这么多重载的openSession方法里面都是选着调用了openSessionFromDataSource()或者openSessionFromConnection(),两个方法逻辑差不过,前者比较常用,先贴图:

主要是先利用TransactionFactory对象构建了事务,用到了刚说的String类型的envirenment变量,还构建了Executor对象,这是Mybatis的一个核心,构建过程就不看了,可以看Executor这个接口里有哪些方法:

可以理解为一个调度对象,Mybatis真正操作数据库的对象,有CRUD,有事务提交回滚,有缓存操作还有关闭连接等。还是贴一看Executor对象的构建过程吧:

 有了Executor调度对象和配置Configuration就可以去构建sqlSession了,即

var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);

new了一个DefaultSqlSession对象,它是SqlSession的实现类,剩下的就是一些初始化工作:

 到这里就读完了,但是上面的流程是MyBatis不和Spring整合自己怎么拿到sqlSession的,如果整合进spring,一开始的步骤会有点不一样,spring的配置类文件springConfiguration里可以重写一个sqlSessionFactoryBean()方法,这个方法返回值类型就是sqlSessionFactoryBean,我们需要做的就是给这个sqlSessionFactoryBean各种设置属性。

Spring自己会利用sqlSessionFactoryBean对象的buildSqlSessionFactory()方法获取sqlSessionFactory对象:

XMLConfigBuilder又来了,剩下的就是大同小异了。

发布了76 篇原创文章 · 获赞 57 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/weixin_42447959/article/details/90664237