MyBatis的實現原理
mybatis底層還是采用原生jdbc來對數據庫進行操作的,只是通過 SqlSessionFactory,SqlSession Executor,StatementHandler,ParameterHandler,ResultHandler和TypeHandler等幾個處理器封裝了這些過程
執行器:Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
參數處理器: ParameterHandler (getParameterObject, setParameters)
結構處理器 ResultSetHandler (handleResultSets, handleOutputParameters)
sql查詢處理器:StatementHandler (prepare, parameterize, batch, update, query)
其中StatementHandler用通過ParameterHandler與ResultHandler分別進行參數預編譯 與結果處理。而ParameterHandler與ResultHandler都使用TypeHandler進行映射。如下圖:
Mybatis工作過程
通過讀mybatis的源碼進行分析mybatis的執行操作的整個過程,我們通過debug調試就可以知道Mybatis每一步做了什么事,我先把debug每一步結果 截圖,然后在分析這個流程。
第一步:讀取配置文件,形成InputStream
1 創建SqlSessionFacotry的過程
從debug調試看出 返回的 sqlSessionFactory 是DefaultSesssionFactory類型的,但是configuration此時已經被初始化了。查看源碼后畫如下創建DefaultSessionFactory的時序圖:
2 創建SqlSession的過程
從debug調試 看出SqlSessinoFactory.openSession() 返回的sqlSession是 DefaultSession類型的,此SqlSession里包含一個Configuration的對象,和一個Executor對象。查看源碼后畫如下創建DefaultSession的時序圖:
3 創建Mapper的過程
從debug調試可以看出,mapper是一個Mapper代理對象,而且初始化了Configuration對象,Executor的對象。查看源碼后畫如下創建Mapper的時序圖:
4 執行CRUD過程
1 以select為例查看各步執行的源碼
1.mapper.selectEmployeeList()其實是MapperProxy執行invoke方法,此方法顯示是判斷Method的方法是不是Object的toString等方法如果不是就執行MapperMethod
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 判斷Method的方法是不是Object的toString等方法
if(Object.class.equals(method.getDeclaringClass())) {
try {
return method.invoke(this, args);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
} else {
//判斷private final Map
MapperMethod mapperMethod = this.cachedMapperMethod(method);
return mapperMethod.execute(this.sqlSession, args);
}
}
//查詢一級緩存和設置一級緩存
private MapperMethod cachedMapperMethod(Method method) {
MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);
if(mapperMethod == null) {
mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());
this.methodCache.put(method, mapperMethod);
}
return mapperMethod;
}
經過上面的調用后進入MapperMethod里面執行
//判斷sql命令類型
public Object execute(SqlSession sqlSession, Object[] args) {
Object param;
Object result;
if(SqlCommandType.INSERT == this.command.getType()) {
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));
} else if(SqlCommandType.UPDATE == this.command.getType()) {
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.update(this.command.getName(), param));
} else if(SqlCommandType.DELETE == this.command.getType()) {
param = this.method.convertArgsToSqlCommandParam(args);
result = this.rowCountResult(sqlSession.delete(this.command.getName(), param));
} else if(SqlCommandType.SELECT == this.command.getType()) {
//我們測試的是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 {
param = this.method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(this.command.getName(), param);
}
} else {
if(SqlCommandType.FLUSH != this.command.getType()) {
throw new BindingException(“Unknown execution method for: ” + this.command.getName());
}
result = sqlSession.flushStatements();
}
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;
}
}
private
//將param做處理 自動處理為param1,param2.。
Object param = this.method.convertArgsToSqlCommandParam(args);
List result;
if(this.method.hasRowBounds()) {
RowBounds rowBounds = this.method.extractRowBounds(args);
//調用該對象的DefaultSqlSession的selectList方法
result = sqlSession.selectList(this.command.getName(), param, rowBounds);
} else {
result = sqlSession.selectList(this.command.getName(), param);
}
return !this.method.getReturnType().isAssignableFrom(result.getClass())?(this.method.getReturnType().isArray()?this.convertToArray(result):this.convertToDeclaredCollection(sqlSession.getConfiguration(), result)):result;
}
//處理參數方法
public Object convertArgsToSqlCommandParam(Object[] args) {
int paramCount = this.params.size();
if(args != null && paramCount != 0) {
if(!this.hasNamedParameters && paramCount == 1) {
return args[((Integer)this.params.keySet().iterator().next()).intValue()];
} else {
Map
int i = 0;
for(Iterator i$ = this.params.entrySet().iterator(); i$.hasNext(); ++i) {
Entry
param.put(entry.getValue(), args[((Integer)entry.getKey()).intValue()]);
String genericParamName = “param” + String.valueOf(i + 1);
if(!param.containsKey(genericParamName)) {
param.put(genericParamName, args[((Integer)entry.getKey()).intValue()]);
}
}
return param;
}
} else {
return null;
}
}
調用DefaultSqlSession的selectList的方法
public
List var5;
try {
//獲取MappedStatement對象
MappedStatement ms = this.configuration.getMappedStatement(statement);
//調用cachingExecutor執行器的方法
var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception var9) {
throw ExceptionFactory.wrapException(“Error querying database. Cause: ” + var9, var9);
} finally {
ErrorContext.instance().reset();
}
return var5;
}
//CachingExector的query方法
public
//
BoundSql boundSql = ms.getBoundSql(parameterObject);
CacheKey key = this.createCacheKey(ms, parameterObject, rowBounds, boundSql);
//調用下2代碼
return this.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
//2代碼
public
Cache cache = ms.getCache();
if(cache != null) {
this.flushCacheIfRequired(ms);
if(ms.isUseCache() && resultHandler == null) {
this.ensureNoOutParams(ms, parameterObject, boundSql);
List
if(list == null) {
//這里是調用Executor里的query方法 如果開啟了緩存這掉CachingExecutor的 如果沒有則是調用BaseExecutor的
list = this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
this.tcm.putObject(cache, key, list);
}
return list;
}
}
return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
BaseExecutor的query方法
public
ErrorContext.instance().resource(ms.getResource()).activity(“executing a query”).object(ms.getId());
if(this.closed) {
throw new ExecutorException(“Executor was closed.”);
} else {
if(this.queryStack == 0 && ms.isFlushCacheRequired()) {
this.clearLocalCache();
}
List list;
try {
++this.queryStack;
list = resultHandler == null?(List)this.localCache.getObject(key):null;
if(list != null) {
this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
} else {
//如果緩存中沒有就從數據庫中查詢
list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
} finally {
--this.queryStack;
}
if(this.queryStack == 0) {
Iterator i$ = this.deferredLoads.iterator();
while(i$.hasNext()) {
BaseExecutor.DeferredLoad deferredLoad = (BaseExecutor.DeferredLoad)i$.next();
deferredLoad.load();
}
this.deferredLoads.clear();
if(this.configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
this.clearLocalCache();
}
}
return list;
}
}
//從數據庫中查詢
private
//放入緩存
this.localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER);
List list;
try {
//此處是調用子Executor的方法,ExecutorType默認是使用的SimpleExecutor
list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
this.localCache.removeObject(key);
}
this.localCache.putObject(key, list);
if(ms.getStatementType() == StatementType.CALLABLE) {
this.localOutputParameterCache.putObject(key, parameter);
}
return list;
}
SimpleExecutor的doQuery方法
public
Statement stmt = null;
List var9;
try {
Configuration configuration = ms.getConfiguration();
//創建StateMentHandler處理器
StatementHandler handler = configuration.newStatementHandler(this.wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
//調用下3的方法
stmt = this.prepareStatement(handler, ms.getStatementLog());
//調用no4的方法
var9 = handler.query(stmt, resultHandler);
} finally {
this.closeStatement(stmt);
}
return var9;
}
//下3方法
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Connection connection = this.getConnection(statementLog);
Statement stmt = handler.prepare(connection);
//SatementHanlder 采用PreparedStatementHandler來實現此方法,而PreparedStatementHandler調用的是父接口ParameterHandler的方法
handler.parameterize(stmt);
return stmt;
}
ParameterHandler參數處理器的方法
public interface ParameterHandler {
Object getParameterObject();
//此方法是用DefaultParameterHandler實現的
void setParameters(PreparedStatement var1) throws SQLException;
}
DefaultParameterHandler默認參數處理器的方法
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity(“setting parameters”).object(this.mappedStatement.getParameterMap().getId());
List
if(parameterMappings != null) {
for(int i = 0; i < parameterMappings.size(); ++i) {
ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i);
if(parameterMapping.getMode() != ParameterMode.OUT) {
String propertyName = parameterMapping.getProperty();
Object value;
if(this.boundSql.hasAdditionalParameter(propertyName)) {
value = this.boundSql.getAdditionalParameter(propertyName);
} else if(this.parameterObject == null) {
value = null;
} else if(this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) {
value = this.parameterObject;
} else {
MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject);
value = metaObject.getValue(propertyName);
}
//這里用調用 TypeHandler類型映射處理器來映射
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if(value == null && jdbcType == null) {
jdbcType = this.configuration.getJdbcTypeForNull();
}
try {
//類型處理器設置參數映射
typeHandler.setParameter(ps, i + 1, value, jdbcType);
} catch (TypeException var10) {
throw new TypeException(“Could not set parameters for mapping: ” + parameterMapping + “。 Cause: ” + var10, var10);
} catch (SQLException var11) {
throw new TypeException(“Could not set parameters for mapping: ” + parameterMapping + “。 Cause: ” + var11, var11);
}
}
}
}
}
no4的方法
public
//此處調用原生sql的處理器
PreparedStatement ps = (PreparedStatement)statement;
//發出原生sql命令
ps.execute();
//采用ResultHandler結果處理器對結果集封裝
return this.resultSetHandler.handleResultSets(ps);
}12345678
ResultHandler代碼
public interface ResultSetHandler {
//此處調用的是DefaultResultSetHandler的方法
void handleOutputParameters(CallableStatement var1) throws SQLException;
}
1234567
DefaultResultSetHandler的方法
public List
ErrorContext.instance().activity(“handling results”).object(this.mappedStatement.getId());
List
int resultSetCount = 0;
ResultSetWrapper rsw = this.getFirstResultSet(stmt);
List
int resultMapCount = resultMaps.size();
this.validateResultMapsCount(rsw, resultMapCount);
while(rsw != null && resultMapCount 》 resultSetCount) {
ResultMap resultMap = (ResultMap)resultMaps.get(resultSetCount);
this.handleResultSet(rsw, resultMap, multipleResults, (ResultMapping)null);
rsw = this.getNextResultSet(stmt);
this.cleanUpAfterHandlingResultSet();
++resultSetCount;
}
String[] resultSets = this.mappedStatement.getResulSets();
if(resultSets != null) {
while(rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = (ResultMapping)this.nextResultMaps.get(resultSets[resultSetCount]);
if(parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = this.configuration.getResultMap(nestedResultMapId);
this.handleResultSet(rsw, resultMap, (List)null, parentMapping);
}
rsw = this.getNextResultSet(stmt);
this.cleanUpAfterHandlingResultSet();
++resultSetCount;
}
}
return this.collapseSingleResultList(multipleResults);
}
//處理結果集
private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List
try {
if(parentMapping != null) {
this.handleRowValues(rsw, resultMap, (ResultHandler)null, RowBounds.DEFAULT, parentMapping);
} else if(this.resultHandler == null) {
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(this.objectFactory);
this.handleRowValues(rsw, resultMap, defaultResultHandler, this.rowBounds, (ResultMapping)null);
multipleResults.add(defaultResultHandler.getResultList());
} else {
this.handleRowValues(rsw, resultMap, this.resultHandler, this.rowBounds, (ResultMapping)null);
}
} finally {
this.closeResultSet(rsw.getResultSet());
}
}
private void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?》 resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
if(resultMap.hasNestedResultMaps()) {
this.ensureNoRowBounds();
this.checkResultHandler();
this.handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {
this.handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?》 resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
DefaultResultContext
this.skipRows(rsw.getResultSet(), rowBounds);
Object rowValue = null;
while(this.shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
ResultMap discriminatedResultMap = this.resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, (String)null);
CacheKey rowKey = this.createRowKey(discriminatedResultMap, rsw, (String)null);
Object partialObject = this.nestedResultObjects.get(rowKey);
if(this.mappedStatement.isResultOrdered()) {
if(partialObject == null && rowValue != null) {
this.nestedResultObjects.clear();
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
}
//獲取行的值
rowValue = this.getRowValue(rsw, discriminatedResultMap, rowKey, (String)null, partialObject);
} else {
rowValue = this.getRowValue(rsw, discriminatedResultMap, rowKey, (String)null, partialObject);
if(partialObject == null) {
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
}
}
}
if(rowValue != null && this.mappedStatement.isResultOrdered() && this.shouldProcessMoreRows(resultContext, rowBounds)) {
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
}
}
String resultMapId = resultMap.getId();
Object resultObject = partialObject;
if(partialObject != null) {
MetaObject metaObject = this.configuration.newMetaObject(partialObject);
this.putAncestor(partialObject, resultMapId, columnPrefix);
this.applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
this.ancestorObjects.remove(resultMapId);
} else {
ResultLoaderMap lazyLoader = new ResultLoaderMap();
resultObject = this.createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
if(resultObject != null && !this.typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
MetaObject metaObject = this.configuration.newMetaObject(resultObject);
boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();
if(this.shouldApplyAutomaticMappings(resultMap, true)) {
foundValues = this.applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
}
foundValues = this.applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
this.putAncestor(resultObject, resultMapId, columnPrefix);
foundValues = this.applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
this.ancestorObjects.remove(resultMapId);
foundValues = lazyLoader.size() 》 0 || foundValues;
resultObject = foundValues?resultObject:null;
}
if(combinedKey != CacheKey.NULL_CACHE_KEY) {
this.nestedResultObjects.put(combinedKey, resultObject);
}
}
return resultObject;
}
private boolean shouldApplyAutomaticMappings(ResultMap resultMap, boolean isNested) {
return resultMap.getAutoMapping() != null?resultMap.getAutoMapping().booleanValue():(isNested?AutoMappingBehavior.FULL == this.configuration.getAutoMappingBehavior():AutoMappingBehavior.NONE != this.configuration.getAutoMappingBehavior());
}
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
List
boolean foundValues = false;
if(autoMapping.size() 》 0) {
Iterator i$ = autoMapping.iterator();
while(true) {
//這里使用了內部類對參數和結果集進行映射
DefaultResultSetHandler.UnMappedColumAutoMapping mapping;
Object value;
do {
if(!i$.hasNext()) {
return foundValues;
}
mapping = (DefaultResultSetHandler.UnMappedColumAutoMapping)i$.next();
value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
} while(value == null && !this.configuration.isCallSettersOnNulls());
if(value != null || !mapping.primitive) {
metaObject.setValue(mapping.property, value);
}
foundValues = true;
}
} else {
return foundValues;
}
}
private static class UnMappedColumAutoMapping {
private final String column;
private final String property;
private final TypeHandler<?》 typeHandler;
private final boolean primitive;
//此處才類型器對結果進行映射
public UnMappedColumAutoMapping(String column, String property, TypeHandler<?》 typeHandler, boolean primitive) {
this.column = column;
this.property = property;
this.typeHandler = typeHandler;
this.primitive = primitive;
}
}
-
mybatis
+關注
關注
0文章
60瀏覽量
6709
發布評論請先 登錄
相關推薦
評論