当前位置: 移动技术网 > IT编程>开发语言>Java > Mybatis获取代理对象

Mybatis获取代理对象

2019年02月25日  | 移动技术网IT编程  | 我要评论
  • mybatis-config.xml里标签可以放置多个environment,这里可以切换test和develop数据源
  • databaseidprovider提供多种数据库,在xml映射文件里选择databaseid即可使用对应的数据库
  • oracle的自增是使用sequence实现的,若要获取插入数据的主键,在xml映射里写上selectkey标签,select seq.nextval from dual;
  • 哪些地方不能使用占位符?比如分表时表名,orderby,desc
  • @mapkey("id")指定返回类型为map时,将id作为key

    1. mybatis参数绑定的过程

    我们写一个usermapper接口,mybatis会为改接口创建一个mapperproxy对象。

    1.1 mapperregistry

    在继续之前,先来了解一下mapperregistry。
  1. mapperregistry是mapper的注册类,提供了注册一个包下面的所有mapper接口。内部维护了一个private final map<class<?>, mapperproxyfactory<?>> knownmappers = new hashmap<class<?>, mapperproxyfactory<?>>();map以mapper接口类为key,value是接口类对应的代理工厂。
    void addmapper(class<t> type)方法简单的将type放进knownmappers里面。不过,这里面还有
        mapperannotationbuilder parser = new mapperannotationbuilder(config, type);
        parser.parse();

这样一个解析操作,暂不做分析。

  1. <t> t getmapper(class<t> type, sqlsession sqlsession)该方法是本类最重要的一个方法了,获取mapper接口的代理对象也正是从该方法获取的。
    该方法实现就是,knownmappers.get(type)得到代理对象工厂mapperproxyfactory,返回的是mapperproxyfactory.newinstance(sqlsession)
    进入该方法发现过程也比较简单,构造了一个mapperproxy对象
   public t newinstance(sqlsession sqlsession) {
    final mapperproxy<t> mapperproxy = new mapperproxy<t>(sqlsession, mapperinterface, methodcache);
    return newinstance(mapperproxy);
  }

再进去看

  protected t newinstance(mapperproxy<t> mapperproxy) {
    return (t) proxy.newproxyinstance(mapperinterface.getclassloader(), new class[] { mapperinterface }, mapperproxy);
  }

发现这就是标准的jdk面向接口的动态代理啊。要问对应的invocationhandler在哪里?mapperproxy就是啦。
至此,mybatis如何获取mapper接口的代理对象已经解决。
再梳理一下整个流程:

sqlsession.getmapper->configuration.getmapper->mapperregistry.getmapper->获取mapper代理对象

1.2

创建好mapperproxy对象之后,调用mapper.xx方法时就会走mapperproxy的invoke方法

public object invoke(object proxy, method method, object[] args) throws throwable {
    try {
      if (object.class.equals(method.getdeclaringclass())) {//如果方法是在object里面的,放行
        return method.invoke(this, args);
      } else if (isdefaultmethod(method)) {
        return invokedefaultmethod(proxy, method, args);
      }
    } catch (throwable t) {
      throw exceptionutil.unwrapthrowable(t);
    }
    final mappermethod mappermethod = cachedmappermethod(method);//缓存method方法
    return mappermethod.execute(sqlsession, args); // 执行
  }

发现关键点在于mappermethod.execute(sqlsession, args)方法

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网