MyBatis的实现原理

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;
}
}

努比亚Z17mini、小米MAX2、荣耀畅玩6X售价都是1699元,特色却有天壤之别
2017年人工智能融资最高5起投资事件
工信部:2010年我国电子信息产业统计
新型光学压力传感器创造敏感型人造皮肤
操作系统产生死锁的原因_必要条件及处理方法
MyBatis的实现原理
MOECEN真无线蓝牙耳机Earbuds X1怎么样 第一手拆解资料
WINCCflexble记录报警
如何减轻米勒电容所引起的寄生导通效应?
BERTWave MP2100B Anritsu安立眼图仪的应用
如何利用单片机PWM实现各种波的输出呢?
浅谈搬运机器人在各行各业中的应用
控制系统典型应用车型 —— 潜入顶升式AMR
用LM317得到直流20V应用电子电路设计
plc设计师不可不知的五大内幕
DeepMind论文登上Nature:困扰数学家几十年的难题,大模型发现全新解
海康威视交通事件采集系统的应用优势及功能实现
物通博联为注塑机远程监控提供物联网解决方案
索尼真无线蓝牙运动耳机WF-XB700 真无线设计让运动更方便
优秀的程序员是怎样的