mybatis配置

mybatis 提供了两种配置方式

1、xml配置,SqlSession可直接调用

2、注解配置

1)可以直接调用接口方法。探求下执行的原理

org.apache.ibatis.session.Configuration.getMapper(Class<T>, SqlSession)
-->> org.apache.ibatis.binding.MapperRegistry.getMapper(Class<T>, SqlSession)
-->> org.apache.ibatis.binding.MapperProxyFactory.newInstance(SqlSession)

可以看到mybatis对 对应的接口(interface)进行了代理,而实现类是org.apache.ibatis.binding.MapperProxy<T>(实现了java.lang.reflect.InvocationHandler接口)。

在该类中可以看到当我们调用接口的方法时,实际调用的是org.apache.ibatis.binding.MapperMethod的org.apache.ibatis.binding.MapperMethod.execute(SqlSession, Object[])方法,该方法里面实际调用的是SqlSession的相关方法。

在该方法中可以看到我们对传入的参数进行了封装org.apache.ibatis.binding.MapperMethod.ParamMap<Object>(继承java.util.HashMap<String, V>)。

我们在接口方法中可以使用org.apache.ibatis.annotations.Param注解参数,value()值就是封装后的map中的key。

Configure对象:封装好的Myabtis的配置对象,程序一启动就加载完成

源码:

public class MapperProxy<T> implements InvocationHandler, Serializable {
  private static final long serialVersionUID = -6424540398559729838L;
  private final SqlSession sqlSession;
  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethod> methodCache;

  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {//是继承子Object的方法,则调用对象的原方法
      try {
        return method.invoke(this, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
     //否则调用自定义业务逻辑
    //创建一个MapperMethod,mybatis的调用的封装 
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }

  private MapperMethod cachedMapperMethod(Method method) {
    //先从方法缓存中取
    //存储对象Key:接口的方法对象,Value:对应的MapperMethod 对象
    MapperMethod mapperMethod = methodCache.get(method);
    if (mapperMethod == null) {//如果没有,则实例化一个
      mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
      methodCache.put(method, mapperMethod);//缓存对象,提高效率,下一次如果还访问的是同一个方法,则直接调用
    }
    return mapperMethod;
  }

}
MapperMethod对象封装了对应SqlSession的调用方法,通过key(接口对象+方法名称)去Configure中对应的MappedStatement(封装好的Myabtis的配置对象)。
参照源码,在execute方法中封装了SqlSession的调用。

3、总结

不管是xml配置,还是注解配置,在程序启动后都会装配为MappedStatement,当调用时本质都是调用的SqlSession的方法。

1) Spring与Mybaits结合时,我们调用接口对象时,实际调用的是依旧是MapperMethod对象的execute方法。

Spring中接口的实例对象是Spring分配给我们的,怎么做的呢?

看mybatis-spring-1.2.2.jar包中的org.mybatis.spring.mapper.MapperFactoryBean对象,

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T>{

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

}

接口对象的代理实体就是getObject方法返回的对象



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值