spring中的mybatis(1)


開門見山

<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

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之工

spring要想集成mybatis,其實它就是把它拉來當「手下」,spring不去再關心數據持久化的具體過程(那都是mybatis要作的),他只要作的就是講mybatis拉到本身的「辦公室」來,給他「一把椅子」,讓他乖乖工做。(而後偷笑!)

spring要想作到這一點其實不是容易的事情,由於spring的辦公室很複雜,mybatis穿過辦公室的門進入辦公室就要大費周章。那麼spring是怎麼作到的呢?下面咱們一塊兒琢磨

一、生成工廠bean

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是執行的呢?

三、整合mybatis

在咱們調用到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

相關文章
相關標籤/搜索