In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
Today, I would like to talk to you about what is the Mybatis Excuter framework, many people may not know much about it. In order to make you understand better, the editor summarizes the following content for you. I hope you can get something from this article.
Excuter framework class diagram
BaseExecutor
In BaseExecutor, the basic implementation of Executor is defined, such as query-level cache, transaction processing and other unchanged parts, and the changing parts such as operating database are implemented by subclasses and template design patterns are used. Let's take a look at the source code of the query method:
@ Overridepublic List query (MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {BoundSql boundSql = ms.getBoundSql (parameter); CacheKey key = createCacheKey (ms, parameter, rowBounds, boundSql); return query (ms, parameter, rowBounds, resultHandler, key, boundSql) } / * * all query operations are finally handled by this method * / @ SuppressWarnings ("unchecked") @ Overridepublic List query (MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {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 ()) {/ / clear the local cache clearLocalCache ();} List list; try {/ / query hierarchy plus a queryStack++; / / query-level cache list = resultHandler = = null? (List) localCache.getObject (key): null; if (list! = null) {/ / processes OUT parameters of stored procedures handleLocallyCachedOutputParameters (ms, key, parameter, boundSql);} else {/ / cache misses, query database list = queryFromDatabase (ms, parameter, rowBounds, resultHandler, key, boundSql);} finally {/ / query hierarchy minus one queryStack-- } if (queryStack = = 0) {for (DeferredLoad deferredLoad: deferredLoads) {deferredLoad.load ();} / issue # 601deferredLoads.clear (); if (configuration.getLocalCacheScope () = = LocalCacheScope.STATEMENT) {/ / issue # 482clearLocalCache ();}} return list;} private List queryFromDatabase (MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {List list / / add cache placeholder localCache.putObject (key, EXECUTION_PLACEHOLDER); try {list = doQuery (ms, parameter, rowBounds, resultHandler, boundSql);} finally {/ / delete cache placeholder localCache.removeObject (key);} / / add query results to local cache localCache.putObject (key, list) If (ms.getStatementType () = = StatementType.CALLABLE) {/ / if it is a stored procedure, the cache parameter localOutputParameterCache.putObject (key, parameter);} return list;}
In the queryFromDatabase () method, we can see that doQuery uses a template method, and the specific logic is implemented by the subclass, which has the advantage that the subclass only cares about the changed part of the program, and the rest is implemented by the parent class. It improves the reusability and expansibility of the code.
SimpleExecutor
An ordinary actuator, which is used by default in Mybatis, each time a new Statement is created. Let's look at the source code of the query method:
@ Overridepublic List doQuery (MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {Statement stmt = null; try {/ / get Mybatis configuration class Configuration configuration = ms.getConfiguration (); / / get StatementHandler StatementHandler handler = configuration.newStatementHandler (wrapper, ms, parameter, rowBounds, resultHandler, boundSql) according to configuration class; / / create Statement stmt = prepareStatement (handler, ms.getStatementLog ()); return handler.query (stmt, resultHandler) } finally {closeStatement (stmt);}} private Statement prepareStatement (StatementHandler handler, Log statementLog) throws SQLException {Statement stmt; / / get Connection connection Connection connection = getConnection (statementLog); / / get Statement stmt = handler.prepare (connection, transaction.getTimeout ()) according to Connection; / / set parameter handler.parameterize (stmt); return stmt;}
We can see that each time a new Statement is created by the stmt = handler.prepare (connection, transaction.getTimeout ()) method.
ReuseExecutor
The executor that can be reused is Statement. Internally, the Statement object is cached with a Map using the sql statement as key. As long as the connection continues to open, the Statement can be reused.
Because every new SqlSession has a new Executor object, the scope of our cached Statement on ReuseExecutor is the same SqlSession, so this cache is not really very useful. Let's take a look at getting the Statement source code directly. The other parts are the same as the SimpleExecutor query method.
Private Statement prepareStatement (StatementHandler handler, Log statementLog) throws SQLException {Statement stmt; BoundSql boundSql = handler.getBoundSql (); String sql = boundSql.getSql (); if (hasStatementFor (sql)) {/ / get the reused Statement stmt = getStatement (sql); applyTransactionTimeout (stmt);} else {/ / New Statement and cache Connection connection = getConnection (statementLog); stmt = handler.prepare (connection, transaction.getTimeout ()); putStatement (sql, stmt) } handler.parameterize (stmt); return stmt;} private boolean hasStatementFor (String sql) {try {/ / determines whether Statement is cached according to sql and whether Connection closes return statementMap.keySet (). Contains (sql) & &! statementMap.get (sql). GetConnection (). IsClosed ();} catch (SQLException e) {return false;}} private Statement getStatement (String s) {return statementMap.get (s) } private void putStatement (String sql, Statement stmt) {statementMap.put (sql, stmt);}
BatchExecutor
Batch executor, batch processing implemented by encapsulating jdbc's statement.addBatch (String sql) and statement.executeBatch ();. The transaction for this executor can only be in manual commit mode.
We usually perform batch processing is generally can also use the way of sql splicing.
When performing batch updates, it is recommended that you do not update too much data at a time. If the amount of update data is large, you can perform it in stages.
CachingExecutor
If secondary caching is turned on, then Mybatis uses the CachingExecutor executor, and CachingExecutor uses decorator mode.
@ Overridepublic List query (MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {/ / get secondary cache Cache cache = ms.getCache (); if (cache! = null) {/ / refresh cache flushCacheIfRequired (ms); if (ms.isUseCache () & & resultHandler = = null) {ensureNoOutParams (ms, boundSql) / / check the cache @ SuppressWarnings ("unchecked") List list = (List) tcm.getObject (cache, key); if (list = = null) {/ / call the decorated method list = delegate.query (ms, parameterObject, rowBounds, resultHandler, key, boundSql); / / put the data into the cache tcm.putObject (cache, key, list) / / issue # 578 and # 116} return list;}} / / No cache found, directly call the decorated method return delegate.query (ms, parameterObject, rowBounds, resultHandler, key, boundSql);}
Through the source code, we found that the whole query process becomes L2-> L1-> DB. The query flow of CachingExecutor adds the query operation of two-level cache.
We rarely use Mybatis's second-level cache when using cache in practice. If you want to do second-level cache, you are recommended to use a third-party cache framework directly at the service level. It is recommended to use layering-cache, a multi-level cache framework generated for monitoring. The query process is L1-> L2-> DB.
BaseExecutor: uses the template method pattern and defines the basic implementation of Executor, which is an abstract class and cannot provide services directly.
SimpleExecutor: an ordinary actuator, which is used by Mybatis by default, and each time a new Statement is created.
ReuseExecutor: Statement executors can be reused, but this Statement cache is only valid in one SqlSession, and we rarely do the same query operations in a SqlSession many times, so the performance improvement is not great.
BatchExecutor: batch executor
CachingExecutor: secondary cache executor, using decorator mode, the entire query flow becomes L2-> L1-> DB. It is recommended to directly use third-party cache shelves, such as layering-cache, a multi-level cache framework for monitoring.
After reading the above, do you have any further understanding of what the Mybatis Excuter framework is? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.