乐趣区

关于mybatis:mybatis源码分析

mybatis 个别集成到 spring 框架中应用,上面介绍如何在 spring 中应用 mybatis

  1. 创立 datasource 实例

     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
         <property name="driverClassName">
             <value>com.mysql.jdbc.Driver</value>
         </property>
         <property name="url">
             <value>jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8</value>
    
         </property>
         <property name="username">
             <value>root</value>
         </property>
         <property name="password">
             <value>xxx</value>
         </property>
     </bean>
  2. 创立 SqlSessionFactoryBean 实例

     <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean">
         <property name="dataSource" ref="dataSource"/>
         <property name="plugins">
             <array>
                 <bean class="com.learn.springmybatis.ExecutorInterceptor"></bean>
             </array>
         </property>
     </bean>
  3. 创立数据库操作的 bean

     <bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
         <property name="mapperInterface" value="com.learn.springmybatis.UserDao"/>
         <property name="sqlSessionFactory" ref="sqlSession"></property>
     </bean>

    当然还有具体 java 代码,这里不体现进去。列出上述配置次要阐明 mybatis 应用的大体流程。业务代码最终是拿数据库操作 bean 实例,如 userDao 去操作数据库。那咱们就从 userDao 开始吧,看看业务代码通过 mybatis 是如何和 db 打交道的。

userDao 的实例化过程

上面是 UserDao 的 java 代码,一个 Interface,外面除了有一个注解,啥都没有。那么它是如何实现数据插入的呢?

public interface UserDao {@Insert("insert into user ( id, name, title) values (#{id},#{name}, #{title})")
    public int insert(User user);
}
  • userDao 是 MapperFactoryBean 创立的
    从 xml 配置咱们能够得悉,userDao 是 MapperFactoryBean 创立,而 MapperFactoryBean 实现类 FactoryBean 接口,Spring 的 FactoryBean 能够依据须要创立不同类型的 bean

    通过 MapperFactoryBean 的 getObject 获取 userDao 实例

      public T getObject() throws Exception {return this.getSqlSession().getMapper(this.mapperInterface);
      }

    this.getSqlSession() 是 new SqlSessionTemplate(sqlSessionFactory)
    最终进入 Configuration 的 getMapper

      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {return this.mapperRegistry.getMapper(type, sqlSession);
      }

    最终调用到 MapperRegistry,具体代码如下,通过 type 在 knownMappers 获取 mapperProxyFactory,这里间接用 knownMappers,那么这个 knownMapper 什么时候初始化好的?先留个疑难,不焦急解答。获取到 mapperProxyFactory 后创立新的实例

      public <T> T getMapper(Class<T> type, SqlSession sqlSession) {MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
          if (mapperProxyFactory == null) {throw new BindingException("Type" + type + "is not known to the MapperRegistry.");
          } else {
              try {return mapperProxyFactory.newInstance(sqlSession);
              } catch (Exception var5) {throw new BindingException("Error getting mapper instance. Cause:" + var5, var5);
              }
          }
      }

    新实例如何创立?看代码,用到 java 的动静代理,sql 的执行,最终会代理到这个 MapperProxy 进行,想晓得 sql 如何执行,只需剖析 MapperProxy 即可。

      protected T newInstance(MapperProxy<T> mapperProxy) {return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
      }
    
      public T newInstance(SqlSession sqlSession) {MapperProxy<T> mapperProxy = new MapperProxy(sqlSession, this.mapperInterface, this.methodCache);
          return this.newInstance(mapperProxy);
      }
  • 未完待续
退出移动版