只是笔记,未详细整理
一.SqlSessionFactory的初始化
将xmlConfigBuilder对象,通过parse()解析成Configuration对象,这个对象有全局配置,以及mapper.xml的配置信息,而mapper.xml解析成了mapperStatement对象,作为map属性放在Configuration对象中.,最后通过new DefaultSqlSessionFactory(Configuration c)返回一个DefaultSqlSessionFactory对象。于是这个DefaultSqlSessionFactory对象就包含了
保存全局配置信息的Configuration对象。
SqlSessionFactoryBuilder提供build方法,
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
try {
//生成XmlConfigBuilder
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//返回SqlSessionFactory,实际就是new DefaultSqlSessionFactory(config);
var5 = this.build(parser.parse());
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException var13) {
;
}
}
return var5;
}
二:获取SqlSession
public SqlSession openSession() {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
Environment environment = this.configuration.getEnvironment();
//加载事务工厂
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//生成执行器,Executor就是增删改查询方法接口
Executor executor = this.configuration.newExecutor(tx, execType);
//返回一个DefaultSqlSession
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
三:获取接口的代理对象
通过DefaultSqlSession中的getMapper方法,其实就是调用configuration.getMapper。而configuration.getMapper其实又是mapperRegistry.getMapper()方法。其中实现是拿到mapperProxyFactory对象,通过mapperProxyFactory工厂newInstance方法,该方法实现
就是获取一个MapperProxy对象,其中封装了sqlSession,所以可以执行查询等操作。
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
四.执行增删改查方法
mybatis中每个Mapper都是一个proxy
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
Object param;
switch(this.command.getType()) {
case INSERT:
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
break;
case UPDATE:
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.update(this.command.getName(), param));
break;
case DELETE:
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.delete(this.command.getName(), param));
break;
case SELECT:
if (this.method.returnsVoid() && this.method.hasResultHandler()) {
this.executeWithResultHandler(sqlSession, args);
result = null;
} else if (this.method.returnsMany()) {
result = this.executeForMany(sqlSession, args);
} else if (this.method.returnsMap()) {
result = this.executeForMap(sqlSession, args);
} else if (this.method.returnsCursor()) {
result = this.executeForCursor(sqlSession, args);
} else {
param = this.method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(this.command.getName(), param);
if (this.method.returnsOptional() && (result == null || !this.method.getReturnType().equals(result.getClass()))) {
result = Optional.ofNullable(result);
}
}
break;
case FLUSH:
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + this.command.getName());
}
if (result == null && this.method.getReturnType().isPrimitive() && !this.method.returnsVoid()) {
throw new BindingException("Mapper method '" + this.command.getName() + " attempted to return null from a method with a primitive return type (" + this.method.getReturnType() + ").");
} else {
return result;
}
}
整体总结:
1.根据配置文件(全局,sql映射)初始化Configuration对象
2.创建一个DefaultSqlSession对象,他里面包含Configuration以及Executor
3.DefaultSqlSession.getMapper(),拿到Mapper接口对应的MapperProxy(包含DefaultSqlSession);
4.执行增删改查方法,
调用DefaultSqlSession的增删改查(Executor)
会创建一个StatementHandler对象(同时也会创建出ParamterHandler和 ResultSetHandler),
调用StatementHandler预编译参数以及设置参数值,
使用ParamterHandler来给sql设置参数
调用statementHandler的增删改查方法
ResultSetHandler封装结果