栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis源码(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis源码(一)

1、启动mybtais

项目结构:

1.1 maven依赖

    
        mysql
        mysql-connector-java
        5.1.47
    
    
        org.mybatis
        mybatis
        3.5.0
        compile
    

1.2 配置文件

mybatis配置文件






    
        

    

    
        
            
            
                
                
                
                
            
        
    
    
        
    

mapper文件






    
        select * from user where username = #{username} and age = #{age}
    



    


1.3 实体类和mapper接口

实体类

public class User {
    
    private String username;
    private int age;
}

mapper接口

public interface UserMapper {

    List> selectAll(Map param);

//    List> selectAll(String username,String age);

    List> select(Map param);
}
1.4 启动类
public class Test1 {

    public static void main(String[] args) throws Exception {
        String resource = "mybatis.xml";
        
        //加载mybatis配置文件
        InputStream resourceAsStream = Test1.class.getResourceAsStream("/" + resource);


        InputStream resourceAsStream1 = Test1.class.getClassLoader().getResourceAsStream(resource);
        System.out.println(resourceAsStream);
        System.out.println(resourceAsStream.hashCode());
        System.out.println(resourceAsStream1);

//        加载配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory =
                new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession sqlSession = sqlSessionFactory.openSession();
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        Configuration configuration = sqlSession.getConfiguration();
        
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        Map param = new HashMap<>();
        param.put("username","zwj");
        param.put("age",22);

        mapper.select(param);

        List> maps = mapper.selectAll(param);
        //因为一级缓存 这里不会调用两次
//        List> maps1 = mapper.selectAll(param);

        //因为二级缓存 这里不会调用两次
//        List> maps2 = mapper1.selectAll(param);
//        List> maps = mapper.selectAll("zwj","1");
        maps.forEach( x -> System.out.println(x));

    }
}
2 mybatis启动流程 2.1 加载mybatis配置文件

SqlSessionFactoryBuilder#build()

public class SqlSessionFactoryBuilder {
   
    public SqlSessionFactory build(InputStream inputStream) {
      //继续
      return build(inputStream, null, null);
    }
    

    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
      try {
        
        XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
        
         //调用下面重载的方法
        return build(parser.parse());
      } catch (Exception e) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", e);
      } finally {
        ErrorContext.instance().reset();
        try {
          inputStream.close();
        } catch (IOException e) {
          // Intentionally ignore. Prefer previous error.
        }
      }
    }
    
    
    //mybatis配置文件解析完成后 会将所有信息封装的全局唯一的Configuraion对象中
    public SqlSessionFactory build(Configuration config) {
      return new DefaultSqlSessionFactory(config);
    }


}
2.2 解析mybatis配置文件

XMLConfigBuilder#parse:解析mybatis.xml里面的节点

public class XMLConfigBuilder extends baseBuilder {
  
    
    public Configuration parse() {
      if (parsed) {
        throw new BuilderException("Each XMLConfigBuilder can only be used once.");
      }
      
      parsed = true;

      
      parseConfiguration(parser.evalNode("/configuration"));
      return configuration;
    }
    
    
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
	    //  
      private void parseConfiguration(XNode root) {
        try {
          //issue #117 read properties first
          
          propertiesElement(root.evalNode("properties"));
          
          Properties settings = settingsAsProperties(root.evalNode("settings"));
          loadCustomVfs(settings);
          loadCustomLogImpl(settings);
          
          typeAliasesElement(root.evalNode("typeAliases"));
          
          pluginElement(root.evalNode("plugins"));
          
          objectFactoryElement(root.evalNode("objectFactory"));


          objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
          //MateObject
          reflectorFactoryElement(root.evalNode("reflectorFactory"));
          
          settingsElement(settings);
          // read it after objectFactory and objectWrapperFactory issue #631
          
          environmentsElement(root.evalNode("environments"));

          databaseIdProviderElement(root.evalNode("databaseIdProvider"));
          
          typeHandlerElement(root.evalNode("typeHandlers"));
          
          mapperElement(root.evalNode("mappers"));
        } catch (Exception e) {
          throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
        }
      }
}
2.3 解析properties标签


private void propertiesElement(XNode context) throws Exception {
  if (context != null) {
    
    Properties defaults = context.getChildrenAsProperties();
    String resource = context.getStringAttribute("resource");
    String url = context.getStringAttribute("url");
    if (resource != null && url != null) {
      throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
    }
    
    if (resource != null) {
      defaults.putAll(Resources.getResourceAsProperties(resource));
    } else if (url != null) {
      defaults.putAll(Resources.getUrlAsProperties(url));
    }
    
    Properties vars = configuration.getVariables();
    if (vars != null) {
      defaults.putAll(vars);
    }
    parser.setVariables(defaults);
    configuration.setVariables(defaults);
  }
}
2.4 解析setting标签
private Properties settingsAsProperties(XNode context) {
  if (context == null) {
    return new Properties();
  }
  Properties props = context.getChildrenAsProperties();
  // Check that all settings are known to the configuration class
  metaClass metaConfig = metaClass.forClass(Configuration.class, localReflectorFactory);
  for (Object key : props.keySet()) {
    
    if (!metaConfig.hasSetter(String.valueOf(key))) {
      throw new BuilderException("The setting " + key + " is not known.  Make sure you spelled it correctly (case sensitive).");
    }
  }
  return props;
}
2.5 日式实现
private void loadCustomLogImpl(Properties props) {
  Class logImpl = resolveClass(props.getProperty("logImpl"));
  configuration.setLogImpl(logImpl);
}
2.6 解析类型别名
private void typeAliasesElement(XNode parent) {
  if (parent != null) {
    for (XNode child : parent.getChildren()) {
      if ("package".equals(child.getName())) {
        String typeAliasPackage = child.getStringAttribute("name");
        
        configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
      } else {
        String alias = child.getStringAttribute("alias");
        String type = child.getStringAttribute("type");
        try {
          
          Class clazz = Resources.classForName(type);
          if (alias == null) {
            typeAliasRegistry.registerAlias(clazz);
          } else {
            typeAliasRegistry.registerAlias(alias, clazz);
          }
        } catch (ClassNotFoundException e) {
          throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + e, e);
        }
      }
    }
  }
}
2.7 解析插件
private void pluginElement(XNode parent) throws Exception {
  if (parent != null) {
    for (XNode child : parent.getChildren()) {
      String interceptor = child.getStringAttribute("interceptor");
      Properties properties = child.getChildrenAsProperties();
      
      Interceptor interceptorInstance = (Interceptor) resolveClass(interceptor).newInstance();
      interceptorInstance.setProperties(properties);
      configuration.addInterceptor(interceptorInstance);
    }
  }
}
2.8 解析对象工厂
private void objectFactoryElement(XNode context) throws Exception {
  if (context != null) {
    String type = context.getStringAttribute("type");
    Properties properties = context.getChildrenAsProperties();
    
    ObjectFactory factory = (ObjectFactory) resolveClass(type).newInstance();
    
    factory.setProperties(properties);
    configuration.setObjectFactory(factory);
  }
}
2.9 给Configuration设置属性
private void settingsElement(Properties props) {
  
  configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL")));
  
  configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE")));
  
  configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true));
  
  configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory")));
  
  configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false));
  
  configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false));
  
  configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true));
  
  configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true));
  
  configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false));
  
  configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE")));
  
  configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null));

  configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null));
  
  configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false));
  
  configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false));
  
  configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION")));
  
  configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER")));
  
  configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString"));
  
  configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true));
  
  configuration.setDefaultscriptingLanguage(resolveClass(props.getProperty("defaultscriptingLanguage")));
  
  configuration.setDefaultEnumTypeHandler(resolveClass(props.getProperty("defaultEnumTypeHandler")));
  
  configuration.setCallSettersonNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false));
  
  configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true));
  configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false));
  
  configuration.setLogPrefix(props.getProperty("logPrefix"));
  
  configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory")));
}
2.10 解析environments标签
private void environmentsElement(XNode context) throws Exception {
  if (context != null) {
    if (environment == null) {
      environment = context.getStringAttribute("default");
    }
    for (XNode child : context.getChildren()) {
      String id = child.getStringAttribute("id");
      
      if (isSpecifiedEnvironment(id)) {
        
        TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));

        DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
        
        DataSource dataSource = dsFactory.getDataSource();
        Environment.Builder environmentBuilder = new Environment.Builder(id)
            .transactionFactory(txFactory)
            .dataSource(dataSource);
        configuration.setEnvironment(environmentBuilder.build());
      }
    }
  }
}
2.11 解析类型处理器
private void typeHandlerElement(XNode parent) {
  if (parent != null) {
    for (XNode child : parent.getChildren()) {
      if ("package".equals(child.getName())) {
        String typeHandlerPackage = child.getStringAttribute("name");
        
        typeHandlerRegistry.register(typeHandlerPackage);
      } else {
        String javaTypeName = child.getStringAttribute("javaType");
        String jdbcTypeName = child.getStringAttribute("jdbcType");
        String handlerTypeName = child.getStringAttribute("handler");
        Class javaTypeClass = resolveClass(javaTypeName);
        JdbcType jdbcType = resolveJdbcType(jdbcTypeName);
        Class typeHandlerClass = resolveClass(handlerTypeName);
        
        if (javaTypeClass != null) {
          if (jdbcType == null) {
            typeHandlerRegistry.register(javaTypeClass, typeHandlerClass);
          } else {
            typeHandlerRegistry.register(javaTypeClass, jdbcType, typeHandlerClass);
          }
        } else {
          typeHandlerRegistry.register(typeHandlerClass);
        }
      }
    }
  }
}
2.12 扫描并解析mapper文件

扫描并解析mapper文件比较重要,下文单独进行说明

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777826.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号