為了理清楚
ibatis一次sql過程中發生了什麼,本文將對ibatis一次sql過程做簡要的分析。
string resource = "mybatis.cfg.xml"
; reader reader = resources.getresourceasreader(resource);
sqlsessionfactory ssf = new sqlsessionfactorybuilder().build(reader);
sqlsession session = ssf.opensession();
try catch (exception e) finally
首先分析下sqlsession session = ssf.opensession(); 這條語句裡面發生了什麼,其實這條語句就是通過sqlsessionfactory工廠獲取一次查詢的session。其中上一句sqlsessionfactory ssf = new sqlsessionfactorybuilder().build(reader); 這句**通過xml檔案獲取到sqlsessionfactory工廠,深入進去發現最終獲取色sqlsessionfactory最終呼叫的是下面這個方法
public sqlsessionfactory build(configuration config)
拿到sqlsessionfactory後我們再去看看sqlsession session = ssf.opensession();這句**究竟幹了什麼?深入**發現ssf.opensession()最終呼叫了一下方法。
private sqlsession opensessionfromdatasource(executortype exectype, transactionisolationlevel level, boolean autocommit) catch (exception e) finally
}
可以從方法中看出,首先獲取載入配置檔案的環境資訊,為後面獲取環境資訊中配置的資料來源做準備,從環境配置中獲取事務工廠。以jdbd事務為例。在jdbctransaction中封裝了資料庫連線操作,因此此處並沒有
建立資料庫連線。接著根據獲取到的事務和執行型別以及是否提交獲取executor例項。其中newexecutor(tx, exectype, autocommit)**如下所示;
public executor newexecutor(transaction transaction, executortype executortype, boolean autocommit) else
if (executortype.reuse == executortype) else
if (cacheenabled)
executor = (executor) interceptorchain.pluginall(executor);
return executor;
}
這裡主要做了三件事
(1)判斷執行器型別,如果配置檔案中沒有配置執行器型別,則採用預設執行型別executortype.******。
(2)根據執行器型別返回不同型別的執行器(執行器有三種,分別是 batchexecutor、******executor和cachingexecutor,後面我們再詳細看看)。
(3)跟執行器繫結***外掛程式。
最後將返回defaultsqlsession(configuration, executor)。 defaultsqlsession實現了sqlsession介面,而sqlsession介面裝封裝了大量跟資料操作有關的方法,可以斷言,所有的操作將在
defaultsqlsession中發生,例子中userinfo user = (userinfo) session.selectone(「user.selectuser」, 「1」); 為例進去看看,這個**最終會執行以下幾個方法。
public
t selectone(string statement, object parameter) else
if (list.size() > 1) else
}public
list
selectlist(string statement, object parameter)
public
list
selectlist(string statement, object parameter, rowbounds rowbounds) catch (exception e) finally
}
public
boundsql boundsql = ms.getboundsql(parameter);
cachekey key = createcachekey(ms, parameter, rowbounds, boundsql);
return query(ms, parameter, rowbounds, resulthandler, key, boundsql);
}
這個方法中進行了sql引數繫結。並且做了相應的快取處理。然後執行了下面這個過載方法
public
list
errorcontext.instance().resource(ms.getresource()).activity("executing a query").object(ms.getid());
if (closed) throw
new executorexception("executor was closed.");
if (querystack == 0 && ms.isflushcacherequired())
list
list;
try else
} finally
if (querystack == 0)
if (configuration.getlocalcachescope() == localcachescope.statement)
} return
list;
}
這個方法中我著重看下這個語句list = queryfromdatabase(ms, parameter, rowbounds, resulthandler, key, boundsql);意思是從資料庫中獲取查詢,具體如下所示:
private
list
list
list;
localcache.putobject(key, execution_placeholder);
try finally
localcache.putobject(key, list);
if (ms.getstatementtype() == statementtype.callable)
return
list;
}
暫時還沒有看到時如何查詢,進一步深入到doquery(ms, parameter, rowbounds, resulthandler, boundsql);這個方法中是個抽象方法在子類中有實現,我們挑選其中乙個實現看了下具體如下所示:
public
configuration configuration = ms.getconfiguration();
statementhandler handler = configuration.newstatementhandler(this, ms, parameter, rowbounds, resulthandler, boundsql);
statement stmt = preparestatement(handler, ms.getstatementlog());
return handler.query(stmt, resulthandler);
}其中preparestatement(handler, ms.getstatementlog());方法如下所示,可以看出真正建立資料庫鏈結在這裡。
private statement preparestatement(statementhandler handler, log statementlog) throws sqlexception else
handler.parameterize(stmt);
return stmt;
}
後面基本就是jdbc運算元據庫的內容了。到此一次sql語句到此完畢。 記錄一次sql優化過程
對於我這種剛剛進入dba行業的人來說sql優化是一件很難的事情。所以今天看了一下別人優化的過程順手記錄的一筆。select distinct vi.policy no from odsdata.policy extend info ei,policy vehicle info vi,policy b...
記一次iBatis自定義sql的坑
在進行定時任務排程job時,在執行到service層時,先是報錯,原因是service方法未增加 transaction註解 override transactional public listmodellistbysql mapparamap 再次除錯,控制台列印sql語句,但是似乎程式停止了一樣...
一次事務過程
第二篇 一次事務過程 對於開發人員來說,我們經常做的是啟動乙個事務,執行sql,提交事務。這就完成了我們的工作。但是,就在這些簡單的動作背後,網路和資料庫都做了些什麼呢。我們都想知道。下面以乙個例項來說明。背景 使用者正執行乙個連線到oracle資料庫的客戶端應用程式,是乙個員工檔案管理程式。過程 ...