欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

结合Mybatis源码说说sqlSession创建流程和从中用到的一些设计模式

程序员文章站 2022-05-29 13:28:53
根据下面这行代码,结合Mybatis源码说说sqlSession创建流程和从中用到的一些设计模式: 1 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 读取配置文件,生成Configuration对象,其中包含数据源、事 ......
  1. 根据下面这行代码,结合mybatis源码说说sqlsession创建流程和从中用到的一些设计模式:

    1 usermapper usermapper = sqlsession.getmapper(usermapper.class);
    1. 读取配置文件,生成configuration对象,其中包含数据源、事务、mapper文件资源以及影响数据库行为属性settings;

    2. sqlsessionfactorybuilder通过读取configuration对象,生成sqlsessionfactory(构建者模式);

       1 public sqlsessionfactory build(reader reader, string environment, properties properties) {
       2   sqlsessionfactory var5;
       3   try {
       4     xmlconfigbuilder parser = new xmlconfigbuilder(reader, environment, properties);
       5     var5 = this.build(parser.parse());
       6   } catch (exception var14) {
       7     throw exceptionfactory.wrapexception("error building sqlsession.", var14);
       8   } finally {
       9     errorcontext.instance().reset();
      10 
      11     try {
      12       reader.close();
      13     } catch (ioexception var13) {
      14     }
      15 
      16   }
      17 
      18   return var5;
      19 }
       1 private void bindmapperfornamespace() {
       2         string namespace = this.builderassistant.getcurrentnamespace();
       3         if (namespace != null) {
       4             class boundtype = null;
       5 
       6             try {
       7                 boundtype = resources.classforname(namespace);
       8             } catch (classnotfoundexception var4) {
       9             }
      10 
      11             if (boundtype != null && !this.configuration.hasmapper(boundtype)) {
      12                 this.configuration.addloadedresource("namespace:" + namespace);
      13                 this.configuration.addmapper(boundtype);
      14             }
      15         }
      16 
      17  }
      1 public sqlsessionfactory build(configuration config) {
      2      return new defaultsqlsessionfactory(config);
      3  }
    3. 在调用build()方法时,通过xmlconfigbuilder类bindmapperfornamespace()方法,将mapper接口注册到mapperregistry类的一个hashmap属性中,key=mapper.class,value=创建当前mapper的工厂;

    4. 通过sqlsessionfactory生成sqlsession实例对象(工厂模式);

    5. sqlsession通过getmapper()方法拿到代理对象(代理模式),运用了jdk动态代理,生成了目标mapper对象的代理对象;

    6. 通过mapperproxyfactory工厂,生成动态代理的代理类是mapperproxy(工厂模式),实现了invocationhandler接口,对invoke()方法进行了包装,将非object类的方法进行了增强,包装成mappermethod,最后执行execute()方法完成sql增删改查的操作。

      public object invoke(object proxy, method method, object[] args) 
           throws throwable {
           try {
               //如果method方法是来自object的方法,那么直接执行,无需增强;
               //意思是假如我们执行的是tostring()方法,是不需要增强的。
               if (object.class.equals(method.getdeclaringclass())) {
                   return method.invoke(this, args);
               }
               if (this.isdefaultmethod(method)) {
                   return this.invokedefaultmethod(proxy, method, args);
               }
           } catch (throwable var5) {
               throw exceptionutil.unwrapthrowable(var5);
           }
           //做了缓存
           mappermethod mappermethod = this.cachedmappermethod(method);
           //执行增删改查操作
           return mappermethod.execute(this.sqlsession, args);
       }