您的位置:首页 > 其它

mybatis_helloworld(2)_源码

2016-07-27 12:16 495 查看
摘录自:http://blog.csdn.net/y172158950/article/details/16982123

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

[java] view plain copy







public static void main(String args[]) throws IOException {

String resource = "com/test/configuration.xml";//获得xml(Mybatis)数据库连接的连接

Reader reader = Resources.getResourceAsReader(resource);//读取里面的文件

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder()

.build(reader);//创建session工厂

SqlSession session = sessionFactory.openSession();//打开session

new Test1().insert(session);

}

1. XML文件资源的获取

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

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

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

[java] view plain copy







<p> public static Reader getResourceAsReader(String resource)

throws IOException

{

Reader reader;</p><p>· //利用InputStream构造Reader

if(charset == null)

reader = new InputStreamReader(getResourceAsStream(resource));

else

reader = new InputStreamReader(getResourceAsStream(resource), charset);

return reader;

}</p><p> </p><p> public static InputStream getResourceAsStream(String resource)

throws IOException

{</p><p> //调用重载方法

return getResourceAsStream(null, resource);

}</p><p> </p><p> public static InputStream getResourceAsStream(ClassLoader loader, String resource)

throws IOException

{</p><p> //调用ClassLoaderWrapper类的方法,利用ClassLoader获取资源

InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);

if(in == null)

throw new IOException((new StringBuilder()).append("Could not find resource ").append(resource).toString());

else

return in;

}</p>

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

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

[java] view plain copy







public InputStream getResourceAsStream(String resource, ClassLoader classLoader)

{

return getResourceAsStream(resource, getClassLoaders(classLoader));

}

ClassLoader[] getClassLoaders(ClassLoader classLoader)

{

return (new ClassLoader[] { //构建新的ClassLoader列表,包含用户创建及默认

classLoader, defaultClassLoader, Thread.currentThread().getContextClassLoader(), getClass().getClassLoader(), systemClassLoader});

}

InputStream getResourceAsStream(String resource, ClassLoader classLoader[])

{

ClassLoader arr$[] = classLoader;

int len$ = arr$.length;

for(int i$ = 0; i$ < len$; i$++) //遍历ClassLoader数组,当某一个Loader成功构建资源则返回

{

ClassLoader cl = arr$[i$];

if(null == cl)

continue;

InputStream returnValue = cl.getResourceAsStream(resource);

if(null == returnValue)

returnValue = cl.getResourceAsStream((new StringBuilder()).append("/").append(resource).toString());

if(null != returnValue)

return returnValue;

}

return null;

}

2. 构建SqlSessionFactory,初始化资源

a) SqlSessionFactory接口介绍

[java] view plain copy







public interface SqlSessionFactory

{

//定义了一系列获取Session的方法,获取Configuration的方法

public abstract SqlSession openSession();

public abstract SqlSession openSession(boolean flag);

public abstract SqlSession openSession(Connection connection);

public abstract SqlSession openSession(TransactionIsolationLevel transactionisolationlevel);

public abstract SqlSession openSession(ExecutorType executortype);

public abstract SqlSession openSession(ExecutorType executortype, boolean flag);

public abstract SqlSession openSession(ExecutorType executortype, TransactionIsolationLevel transactionisolationlevel);

public abstract SqlSession openSession(ExecutorType executortype, Connection connection);

public abstract Configuration getConfiguration();

}

b) SqlSessionFactory接口构建

i. SqlSessionFactoryBuilder类:构建SqlSessionFactory

ii. 我们使用的方法:build

[java] view plain copy







public SqlSessionFactory build(Reader reader)

{

//调用重载方法

return build(reader, null, null);

}

public SqlSessionFactory build(Reader reader, String environment, Properties properties)

{

try

{

SqlSessionFactory sqlsessionfactory;

try

{

//根据reader封装XMLConfig相关信息

XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);

//调用重载方法

sqlsessionfactory = build(parser.parse());

}

catch(Exception e)

{

throw ExceptionFactory.wrapException("Error building SqlSession.", e);

}

return sqlsessionfactory;

}

finally

{

ErrorContext.instance().reset();

try

{

reader.close();

}

catch(IOException e) { }

}

}

public SqlSessionFactory build(Configuration config)

{

//依据配置信息构建默认的SqlSessionFactory实现

return new DefaultSqlSessionFactory(config);

}

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

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

[java] view plain copy







public Configuration parse()

{

if(parsed)

{

throw new BuilderException("Each MapperConfigParser can only be used once.");

} else

{

parsed = true;

parseConfiguration(parser.evalNode("/configuration")); //XML文件的根目录

return configuration;

}

}

private void parseConfiguration(XNode root)

{

try

{

typeAliasesElement(root.evalNode("typeAliases")); //解析typeAliases

pluginElement(root.evalNode("plugins"));

objectFactoryElement(root.evalNode("objectFactory"));

objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));

propertiesElement(root.evalNode("properties"));

settingsElement(root.evalNode("settings"));

environmentsElement(root.evalNode("environments")); //数据库配置

typeHandlerElement(root.evalNode("typeHandlers"));

mapperElement(root.evalNode("mappers")); //解析sql语句配置文件

}

catch(Exception e)

{

throw new BuilderException((new StringBuilder()).append("Error parsing SQL Mapper Configuration. Cause: ").append(e).toString(), e);

}

}

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

[java] view plain copy







protected Environment environment;

protected boolean lazyLoadingEnabled;

protected boolean aggressiveLazyLoading;

protected boolean multipleResultSetsEnabled;

protected boolean useGeneratedKeys;

protected boolean useColumnLabel;

protected boolean cacheEnabled;

protected Integer defaultStatementTimeout;

protected ExecutorType defaultExecutorType;

protected AutoMappingBehavior autoMappingBehavior;

protected Properties variables;

protected ObjectFactory objectFactory;

protected ObjectWrapperFactory objectWrapperFactory;

protected MapperRegistry mapperRegistry;

protected final InterceptorChain interceptorChain;

protected final TypeHandlerRegistry typeHandlerRegistry;

protected final TypeAliasRegistry typeAliasRegistry;

protected final Map mappedStatements;

protected final Map caches;

protected final Map resultMaps;

protected final Map parameterMaps;

protected final Map keyGenerators;

protected final Set loadedResources;

protected final Map sqlFragments;

protected final Collection incompleteStatements;

protected final Collection incompleteCacheRefs;

protected final Map cacheRefMap;

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

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

[java] view plain copy







public SqlSession openSession()

{

return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);

}

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)

{

Connection connection = null;

try

{

DefaultSqlSession defaultsqlsession;

try

{

Environment environment = configuration.getEnvironment();

//获取javax.sql.DataSource

DataSource dataSource = getDataSourceFromEnvironment(environment);

TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

//获取java.sql.Connection

connection = dataSource.getConnection();

if(level != null)

connection.setTransactionIsolation(level.getLevel());

connection = wrapConnection(connection);

//一系列的封装,把Connection包装成了DefaultSqlSession(SqlSession的实现类)

org.apache.ibatis.transaction.Transaction tx = transactionFactory.newTransaction(connection, autoCommit);

org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType);

defaultsqlsession = new DefaultSqlSession(configuration, executor, autoCommit);

}

catch(Exception e)

{

closeConnection(connection);

throw ExceptionFactory.wrapException((new StringBuilder()).append("Error opening session. Cause: ").append(e).toString(), e);

}

return defaultsqlsession;

}

finally

{

ErrorContext.instance().reset();

}

}

4. insert数据的实现

[java] view plain copy







public int insert(String statement, Object parameter)

{

return update(statement, parameter);

}

public int update(String statement, Object parameter)

{

try

{

int i;

try

{

dirty = true;

//根据Mapper.xml配置文件中的id找到Sql语句

org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement);

//这个执行器是不是见过?构建DefaultSqlSession时传过来的

// org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType);

i = executor.update(ms, wrapCollection(parameter));

}

catch(Exception e)

{

throw ExceptionFactory.wrapException((new StringBuilder()).append("Error updating database. Cause: ").append(e).toString(), e);

}

return i;

}

finally

{

ErrorContext.instance().reset();

}

}

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

i. 调用哪个executor?

[java] view plain copy







public Executor newExecutor(Transaction transaction, ExecutorType executorType)

{

executorType = executorType != null ? executorType : defaultExecutorType; //我们使用的是默认的Type(SIMPLE)

executorType = executorType != null ? executorType : ExecutorType.SIMPLE;

Executor executor;

if(ExecutorType.BATCH == executorType)

executor = new BatchExecutor(this, transaction);

else

if(ExecutorType.REUSE == executorType)

executor = new ReuseExecutor(this, transaction);

else

executor = new SimpleExecutor(this, transaction);

if(cacheEnabled)

executor = new CachingExecutor(executor);

executor = (Executor)interceptorChain.pluginAll(executor);

return executor;

}

ii. SimpleExecutor的update方法实现

[java] view plain copy







//父类BaseExecutor的update方法,调用了doUpdate方法

public int update(MappedStatement ms, Object parameter)

throws SQLException

{

ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());

if(closed)

{

throw new ExecutorException("Executor was closed.");

} else

{

clearLocalCache();

return doUpdate(ms, parameter);

}

}

//子类SimpleExecutor重写了doUpdate方法

public int doUpdate(MappedStatement ms, Object parameter)

throws SQLException

{

//java.sql.Statement

Statement stmt = null;

int i;

try

{

Configuration configuration = ms.getConfiguration();

StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null);

//大概就是拼Sql,生成对应的Statement,执行Sql,封装数据了(这块比较复杂,下次再看了)

stmt = prepareStatement(handler);

i = handler.update(stmt);

}

finally

{

closeStatement(stmt);

}

return i;

}

看了一回源码,也感觉高端大气上档次了,下次画个图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: