打赏

mybatis_helloworld(2)_源码

摘录自:http://blog.csdn.net/y172158950/article/details/16982123

在helloworld(1)中,分析了insert一条数据的流程,现在分析下源码:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public static void main(String args[]) throws IOException {  
  2.         String resource = "com/test/configuration.xml";//获得xml(Mybatis)数据库连接的连接  
  3.         Reader reader = Resources.getResourceAsReader(resource);//读取里面的文件  
  4.         SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder()  
  5.                 .build(reader);//创建session工厂  
  6.         SqlSession session = sessionFactory.openSession();//打开session  
  7.         new Test1().insert(session);  
  8.     }  

1. XML文件资源的获取

  a)包路径:org.apache.ibatis.io

  b)Resources类:定义了一系列的静态方法,用于获取资源(ClassLoader,URL,InputStream,Read,File,Properties,Charset)

  c)我们用到的getResourceAsReader,getResourceAsStream方法

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1.   <p>    public static Reader getResourceAsReader(String resource)  
  2.         throws IOException  
  3.     {  
  4.         Reader reader;</p><p>·       //利用InputStream构造Reader  
  5.         if(charset == null)  
  6.             reader = new InputStreamReader(getResourceAsStream(resource));  
  7.         else  
  8.             reader = new InputStreamReader(getResourceAsStream(resource), charset);  
  9.         return reader;  
  10.     }</p><p>   </p><p>    public static InputStream getResourceAsStream(String resource)  
  11.         throws IOException  
  12.     {</p><p>        //调用重载方法  
  13.         return getResourceAsStream(null, resource);  
  14.     }</p><p> </p><p>    public static InputStream getResourceAsStream(ClassLoader loader, String resource)  
  15.         throws IOException  
  16.     {</p><p>        //调用ClassLoaderWrapper类的方法,利用ClassLoader获取资源  
  17.         InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);  
  18.         if(in == null)  
  19.             throw new IOException((new StringBuilder()).append("Could not find resource ").append(resource).toString());  
  20.         else  
  21.             return in;  
  22.     }</p>  

d)ClassLoaderWrapper类:封装了一个ClassLoader数组,通过ClassLoader获取资源

e)我们用到的getResourceAsStream,getClassLoaders方法

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public InputStream getResourceAsStream(String resource, ClassLoader classLoader)  
  2. {  
  3.     return getResourceAsStream(resource, getClassLoaders(classLoader));  
  4. }  
  5.   
  6. ClassLoader[] getClassLoaders(ClassLoader classLoader)  
  7. {  
  8.     return (new ClassLoader[] {  //构建新的ClassLoader列表,包含用户创建及默认  
  9.         classLoader, defaultClassLoader, Thread.currentThread().getContextClassLoader(), getClass().getClassLoader(),           systemClassLoader});  
  10. }  
  11.   
  12. InputStream getResourceAsStream(String resource, ClassLoader classLoader[])  
  13. {  
  14.     ClassLoader arr$[] = classLoader;  
  15.     int len$ = arr$.length;  
  16.     for(int i$ = 0; i$ < len$; i$++)    //遍历ClassLoader数组,当某一个Loader成功构建资源则返回  
  17.     {  
  18.         ClassLoader cl = arr$[i$];  
  19.         if(null == cl)  
  20.             continue;  
  21.         InputStream returnValue = cl.getResourceAsStream(resource);  
  22.         if(null == returnValue)  
  23.             returnValue = cl.getResourceAsStream((new StringBuilder()).append("/").append(resource).toString());  
  24.         if(null != returnValue)  
  25.             return returnValue;  
  26.     }  
  27.   
  28.     return null;  
  29. }  

2. 构建SqlSessionFactory,初始化资源

a) SqlSessionFactory接口介绍

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public interface SqlSessionFactory  
  2. {  
  3.     //定义了一系列获取Session的方法,获取Configuration的方法  
  4.     public abstract SqlSession openSession();  
  5.   
  6.     public abstract SqlSession openSession(boolean flag);  
  7.   
  8.     public abstract SqlSession openSession(Connection connection);  
  9.   
  10.     public abstract SqlSession openSession(TransactionIsolationLevel transactionisolationlevel);  
  11.   
  12.     public abstract SqlSession openSession(ExecutorType executortype);  
  13.   
  14.     public abstract SqlSession openSession(ExecutorType executortype, boolean flag);  
  15.   
  16.     public abstract SqlSession openSession(ExecutorType executortype, TransactionIsolationLevel transactionisolationlevel);  
  17.   
  18.     public abstract SqlSession openSession(ExecutorType executortype, Connection connection);  
  19.   
  20.     public abstract Configuration getConfiguration();  
  21. }  

b) SqlSessionFactory接口构建

   i. SqlSessionFactoryBuilder类:构建SqlSessionFactory

   ii. 我们使用的方法:build

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public SqlSessionFactory build(Reader reader)  
  2.     {  
  3.         //调用重载方法  
  4.         return build(reader, null, null);  
  5.     }  
  6.   
  7.     public SqlSessionFactory build(Reader reader, String environment, Properties properties)  
  8.     {  
  9.         try  
  10.         {  
  11.             SqlSessionFactory sqlsessionfactory;  
  12.             try  
  13.             {  
  14.                 //根据reader封装XMLConfig相关信息  
  15.                 XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);  
  16.                 //调用重载方法  
  17.                 sqlsessionfactory = build(parser.parse());  
  18.             }  
  19.             catch(Exception e)  
  20.             {  
  21.                 throw ExceptionFactory.wrapException("Error building SqlSession.", e);  
  22.             }  
  23.             return sqlsessionfactory;  
  24.         }  
  25.         finally  
  26.         {  
  27.             ErrorContext.instance().reset();  
  28.             try  
  29.             {  
  30.                 reader.close();  
  31.             }  
  32.             catch(IOException e) { }  
  33.         }  
  34.     }  
  35.       
  36.     public SqlSessionFactory build(Configuration config)  
  37.     {  
  38.         //依据配置信息构建默认的SqlSessionFactory实现  
  39.         return new DefaultSqlSessionFactory(config);  
  40.     }  

c) XMLConfigBuilder类:解析XML配置文件

  i. 用到的主要方法:parse,parseConfiguration(就是按XML结构顺序解析,分别获取配置[SAX解析]);将数据封装到父类的configuration对象中

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public Configuration parse()  
  2.    {  
  3.        if(parsed)  
  4.        {  
  5.            throw new BuilderException("Each MapperConfigParser can only be used once.");  
  6.        } else  
  7.        {  
  8.            parsed = true;  
  9.            parseConfiguration(parser.evalNode("/configuration"));   //XML文件的根目录  
  10.            return configuration;  
  11.        }  
  12.    }  
  13.   
  14.    private void parseConfiguration(XNode root)  
  15.    {  
  16.        try  
  17.        {  
  18.            typeAliasesElement(root.evalNode("typeAliases"));    //解析typeAliases  
  19.            pluginElement(root.evalNode("plugins"));  
  20.            objectFactoryElement(root.evalNode("objectFactory"));  
  21.            objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));  
  22.            propertiesElement(root.evalNode("properties"));  
  23.            settingsElement(root.evalNode("settings"));  
  24.            environmentsElement(root.evalNode("environments"));   //数据库配置  
  25.            typeHandlerElement(root.evalNode("typeHandlers"));      
  26.            mapperElement(root.evalNode("mappers"));    //解析sql语句配置文件  
  27.        }  
  28.        catch(Exception e)  
  29.        {  
  30.            throw new BuilderException((new StringBuilder()).append("Error parsing SQL Mapper Configuration. Cause: ").append(e).toString(), e);  
  31.        }  
  32.    }  

d)Configuration类:基本就是封装一系列的数据;看一下成员变量

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected Environment environment;  
  2.     protected boolean lazyLoadingEnabled;  
  3.     protected boolean aggressiveLazyLoading;  
  4.     protected boolean multipleResultSetsEnabled;  
  5.     protected boolean useGeneratedKeys;  
  6.     protected boolean useColumnLabel;  
  7.     protected boolean cacheEnabled;  
  8.     protected Integer defaultStatementTimeout;  
  9.     protected ExecutorType defaultExecutorType;  
  10.     protected AutoMappingBehavior autoMappingBehavior;  
  11.     protected Properties variables;  
  12.     protected ObjectFactory objectFactory;  
  13.     protected ObjectWrapperFactory objectWrapperFactory;  
  14.     protected MapperRegistry mapperRegistry;  
  15.     protected final InterceptorChain interceptorChain;  
  16.     protected final TypeHandlerRegistry typeHandlerRegistry;  
  17.     protected final TypeAliasRegistry typeAliasRegistry;  
  18.     protected final Map mappedStatements;  
  19.     protected final Map caches;  
  20.     protected final Map resultMaps;  
  21.     protected final Map parameterMaps;  
  22.     protected final Map keyGenerators;  
  23.     protected final Set loadedResources;  
  24.     protected final Map sqlFragments;  
  25.     protected final Collection incompleteStatements;  
  26.     protected final Collection incompleteCacheRefs;  
  27.     protected final Map cacheRefMap;  

e)DefaultSqlSessionFactory类:SqlSessionFactory接口实现类,并持有一个Configuration对象;我们实现获取SqlSeesion对象应用的此类的方法。

3. 回过头来,再看看SqlSession session = sessionFactory.openSession();这行代码的实现

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public SqlSession openSession()  
  2.     {  
  3.         return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);  
  4.     }  
  5.       
  6.     private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)  
  7.     {  
  8.         Connection connection = null;  
  9.         try  
  10.         {  
  11.             DefaultSqlSession defaultsqlsession;  
  12.             try  
  13.             {  
  14.                 Environment environment = configuration.getEnvironment();  
  15.                 //获取javax.sql.DataSource  
  16.                 DataSource dataSource = getDataSourceFromEnvironment(environment);  
  17.                 TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);  
  18.                 //获取java.sql.Connection  
  19.                 connection = dataSource.getConnection();  
  20.                 if(level != null)  
  21.                     connection.setTransactionIsolation(level.getLevel());                  
  22.                 connection = wrapConnection(connection);  
  23.                 //一系列的封装,把Connection包装成了DefaultSqlSession(SqlSession的实现类)  
  24.                 org.apache.ibatis.transaction.Transaction tx = transactionFactory.newTransaction(connection, autoCommit);  
  25.                 org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType);  
  26.                 defaultsqlsession = new DefaultSqlSession(configuration, executor, autoCommit);  
  27.             }  
  28.             catch(Exception e)  
  29.             {  
  30.                 closeConnection(connection);  
  31.                 throw ExceptionFactory.wrapException((new StringBuilder()).append("Error opening session.  Cause: ").append(e).toString(), e);  
  32.             }  
  33.             return defaultsqlsession;  
  34.         }  
  35.         finally  
  36.         {  
  37.             ErrorContext.instance().reset();  
  38.         }  
  39.     }  

4. insert数据的实现

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public int insert(String statement, Object parameter)  
  2.    {  
  3.        return update(statement, parameter);  
  4.    }  
  5.      
  6.     public int update(String statement, Object parameter)  
  7.    {  
  8.        try  
  9.        {  
  10.            int i;  
  11.            try  
  12.            {  
  13.                dirty = true;  
  14.                //根据Mapper.xml配置文件中的id找到Sql语句  
  15.                org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement);  
  16.                //这个执行器是不是见过?构建DefaultSqlSession时传过来的  
  17.                // org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType);  
  18.                i = executor.update(ms, wrapCollection(parameter));  
  19.            }  
  20.            catch(Exception e)  
  21.            {  
  22.                throw ExceptionFactory.wrapException((new StringBuilder()).append("Error updating database.  Cause: ").append(e).toString(), e);  
  23.            }  
  24.            return i;  
  25.        }  
  26.        finally  
  27.        {  
  28.            ErrorContext.instance().reset();  
  29.        }  
  30.    }  

a) 找一下executor,看看其update方法

   i. 调用哪个executor?

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public Executor newExecutor(Transaction transaction, ExecutorType executorType)  
  2.     {  
  3.         executorType = executorType != null ? executorType : defaultExecutorType;  //我们使用的是默认的Type(SIMPLE)  
  4.         executorType = executorType != null ? executorType : ExecutorType.SIMPLE;  
  5.         Executor executor;  
  6.         if(ExecutorType.BATCH == executorType)  
  7.             executor = new BatchExecutor(this, transaction);  
  8.         else  
  9.         if(ExecutorType.REUSE == executorType)  
  10.             executor = new ReuseExecutor(this, transaction);  
  11.         else  
  12.             executor = new SimpleExecutor(this, transaction);  
  13.         if(cacheEnabled)  
  14.             executor = new CachingExecutor(executor);  
  15.         executor = (Executor)interceptorChain.pluginAll(executor);  
  16.         return executor;  
  17.     }  

  ii. SimpleExecutor的update方法实现

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. //父类BaseExecutor的update方法,调用了doUpdate方法  
  2.         public int update(MappedStatement ms, Object parameter)  
  3.         throws SQLException  
  4.     {  
  5.         ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());  
  6.         if(closed)  
  7.         {  
  8.             throw new ExecutorException("Executor was closed.");  
  9.         } else  
  10.         {  
  11.             clearLocalCache();  
  12.             return doUpdate(ms, parameter);  
  13.         }  
  14.     }  
  15.       
  16.     //子类SimpleExecutor重写了doUpdate方法  
  17.     public int doUpdate(MappedStatement ms, Object parameter)  
  18.         throws SQLException  
  19.     {  
  20.         //java.sql.Statement  
  21.         Statement stmt = null;  
  22.         int i;  
  23.         try  
  24.         {  
  25.             Configuration configuration = ms.getConfiguration();  
  26.             StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null);  
  27.             //大概就是拼Sql,生成对应的Statement,执行Sql,封装数据了(这块比较复杂,下次再看了)  
  28.             stmt = prepareStatement(handler);  
  29.               
  30.             i = handler.update(stmt);  
  31.         }  
  32.         finally  
  33.         {  
  34.             closeStatement(stmt);  
  35.         }  
  36.         return i;  
  37.     }  

看了一回源码,也感觉高端大气上档次了,下次画个图

posted @ 2016-07-27 12:16  海米傻傻  阅读(164)  评论(0编辑  收藏  举报