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他要做什么呢?

糊涂门之猜呀猜

这件事情我们不妨去猜一猜:

第一猜:spring都是通过自己的容器管管理类的,那么mybatis要想整合,最终要包装成spring能够操控的factorybean。从名字SqlSessionFactoryBean有没有感?(吼吼)

第二猜:如果我们自己使用mybatis,其实就是调用底层他的接口去实现功能,那么spring把这件事情自己封装了,让我们调用他的 方法,他再去调用mybatis的方法,这样是不是就实现了mybatis和spring的整合?(呲牙)

在深入SqlSessionFactoryBean类具体源码之前,我们来看看mybatis的配置通常是什么样子的。

点点mybatis

mybatis的内容包括哪些重要的部分,如果不清楚这些那么我们也无法知道spring是如何包装mybatis的。那么在没有spring之前,mybatis是如何自行工作的呢?
mybatis主要包括以下这七项配置项。如想深入配置具体内容请查看参考文献
 properties:用于配置属性信息。 settings:用于配置MyBatis的运行时方式。 typeAliases:配置类型别名,可以在xml中用别名取代全限定名。 typeHandlers:配置类型处理器。 plugins:配置拦截器,用于拦截sql语句的执行。 environments:配置数据源信息、连接池、事务属性等。 mappers:配置SQL映射文件。没有spring之前,使用mybatis需要以下几步骤。

1、jdk、tomcat(或者其他web容器),必需的。

2、创建一个web项目

3、解压mybatis3.2.3.zip文件,把mybatis-3.2.3.jar和lib目录下的所有jar包复制到WEB-INF/lib

4、复制mysql-connector-java-5.1.14.jar到WEB-INF/lib

5、在mysql创建一个mybatis数据库,新建一个user表,里面有id,name,password。

6、新建一个实体。

7、创建一个mapper接口

8、创建一个mapper.xml,里面写和mapper接口中定义一致的sql语句。

9、在classpath下创建mybatis配置文件mybatis-confi.xml,里面配置

<setting>
<typeAliases>
<environments>
<mappers>

10、新建一个能够生成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是怎么做到的呢?下面我们一起琢磨

1、生成工厂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的实例生成,那么它有是如何注入到容器中的呢?

2、注入容器

有了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

spring中的mybatis(1)_第1张图片



最终xml中配置的mybatis类都成为了BeanDefinition放入到了spring容器中去管理。那么最终我们去执行sql语句的时候spring是执行的呢?

3、整合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);
}


spring中的mybatis(1)_第2张图片


   下面的章节我会详细分析各个部分。



参考文献:

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


你可能感兴趣的:(spring中的mybatis(1))