<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:com/mybatis/mapping/*.xml" />
</bean>
咱們知道這個類SqlSessionFactoryBean明顯就是一個spring的類。咱們也知道mybatis是持久化數據的框架。那麼spring若是要整合mybatis他要作什麼呢?html
這件事情咱們不妨去猜一猜:java
第一猜:spring都是經過本身的容器管管理類的,那麼mybatis要想整合,最終要包裝成spring可以操控的factorybean。從名字SqlSessionFactoryBean有沒有感?(吼吼)mysql
第二猜:若是咱們本身使用mybatis,其實就是調用底層他的接口去實現功能,那麼spring把這件事情本身封裝了,讓咱們調用他的 方法,他再去調用mybatis的方法,這樣是否是就實現了mybatis和spring的整合?(呲牙)git
在深刻SqlSessionFactoryBean類具體源碼以前,咱們來看看mybatis的配置一般是什麼樣子的。github
mybatis的內容包括哪些重要的部分,若是不清楚這些那麼咱們也沒法知道spring是如何包裝mybatis的。那麼在沒有spring以前,mybatis是如何自行工做的呢?
mybatis主要包括如下這七項配置項。如想深刻配置具體內容請查看參考文獻
properties:用於配置屬性信息。 settings:用於配置MyBatis的運行時方式。 typeAliases:配置類型別名,能夠在xml中用別名取代全限定名。 typeHandlers:配置類型處理器。 plugins:配置攔截器,用於攔截sql語句的執行。 environments:配置數據源信息、鏈接池、事務屬性等。 mappers:配置SQL映射文件。沒有spring以前,使用mybatis須要如下幾步驟。
web
一、jdk、tomcat(或者其餘web容器),必需的。spring
二、建立一個web項目sql
三、解壓mybatis3.2.3.zip文件,把mybatis-3.2.3.jar和lib目錄下的全部jar包複製到WEB-INF/lib數據庫
四、複製mysql-connector-java-5.1.14.jar到WEB-INF/libtomcat
五、在mysql建立一個mybatis數據庫,新建一個user表,裏面有id,name,password。
六、新建一個實體。
七、建立一個mapper接口
八、建立一個mapper.xml,裏面寫和mapper接口中定義一致的sql語句。
九、在classpath下建立mybatis配置文件mybatis-confi.xml,裏面配置
<setting>
<typeAliases>
<environments>
<mappers>
十、新建一個可以生成mybatis工廠的單例類
public class MybatisUtil {
private static SqlSessionFactory sqlMapper; private static Reader reader; static { try { reader = Resources.getResourceAsReader("mybatis-config.xml"); sqlMapper = new SqlSessionFactoryBuilder().build(reader); } catch (Exception e) { e.printStackTrace(); } } public static SqlSessionFactory getInstance() { return sqlMapper; } }
最後,使用方式就是
建立工廠類-》打開session-》執行mapper接口中的語句(insert、update、select、delete)-》關閉session
spring要想集成mybatis,其實它就是把它拉來當「手下」,spring不去再關心數據持久化的具體過程(那都是mybatis要作的),他只要作的就是講mybatis拉到本身的「辦公室」來,給他「一把椅子」,讓他乖乖工做。(而後偷笑!)
spring要想作到這一點其實不是容易的事情,由於spring的辦公室很複雜,mybatis穿過辦公室的門進入辦公室就要大費周章。那麼spring是怎麼作到的呢?下面咱們一塊兒琢磨
SqlSessionFactoryBean類實現了接口FactoryBean<SqlSessionFactory>, InitializingBean。最終spring在調用getBean的時候返回的並非類SqlSessionFactoryBean,而是他的屬性類SqlSessionFactory的實例,代碼以下:
public void afterPropertiesSet() throws Exception { notNull(dataSource, "Property 'dataSource' is required"); notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required"); this.sqlSessionFactory = buildSqlSessionFactory(); }public SqlSessionFactory getObject() throws Exception { if (this.sqlSessionFactory == null) { afterPropertiesSet(); } return this.sqlSessionFactory; }
至此,咱們看到了sqlSessionFactory的實例生成,那麼它有是如何注入到容器中的呢?
有了sqlSessionFactory 就要把它放置到容器中去管理。那麼spring的容器如何載入這個類實例的哪?這裏說的sqlSessionFactory是配置文件中SqlSessionFactoryBean對應的id。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath*:com/mybatis/mapping/*.xml" /></bean>
第一步:查看到web,來看看spring容器啓動的入口類:org.springframework.web.context.ContextLoaderListener
這個類直接調用了方法contextInitialized初始化WebApplicationContext
最終xml中配置的mybatis類都成爲了BeanDefinition放入到了spring容器中去管理。那麼最終咱們去執行sql語句的時候spring是執行的呢?
在咱們調用到sql語句的時候,會把相應的mybatis代理類封裝到HandlerMethod類中
設置到攔截器鏈條中(如圖)
//類:AbstractHandlerMapping public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } return getHandlerExecutionChain(handler, request); }
而後spring的代理工廠會根據這個攔截器鏈條去調用mybatis的代理類去執行sql語句。
//MapperProxy<T> final MapperMethod mapperMethod = cachedMapperMethod(method); return mapperMethod.execute(sqlSession, args); }

下面的章節我會詳細分析各個部分。
參考文獻:
http://my.oschina.net/u/1269959/blog/521703
http://blog.csdn.net/etttttss/article/details/8902125
http://mybatis.github.io/mybatis-3/zh/configuration.html
http://www.luoshengsha.com/266.html