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--
This article will explain in detail how to understand the Cache in the Mybatis source code, the content of the article is of high quality, so the editor will share it with you for reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.
Usage scenarios for caching
The data calculated through complex business may spend a lot of time in the process of calculation, and the data need to be cached.
Read more and write less data
Key points of cache design
Cache capacity
Valid time of the cache
Problems that may exist in practice: cache penetration
Whether the access buffer exists or not, go directly to the database. Usually the key you look up does not have a corresponding cache and can be designed to return a null value without looking up the database.
Cache avalanche
A large amount of cache penetration will lead to a large number of requests, and access will fall on the database, resulting in a cache avalanche. So if the accessed key cannot be found in the cache, do not query the database directly, that is, to avoid cache penetration, you can set the cache to permanent cache, and then update the cache regularly through the background. You can also add lock protection for cache updates to ensure that only one thread currently updates the data.
Cache Analysis and Learning in Mybatis first-level cache and second-level cache of MyBatis
First-level cache
Use range: SESSION,STATEMENT. The default is SESSION. If you do not want to use first-level cache, you can change it to STATEMENT, and the cache will be cleared after each call.
/ / STATEMENT or SESSION. Default is SESSION.
The process executed by the first-level cache:
/ / BaseExecutor.querypublic 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 ());... List list; try {. / / first look up list = resultHandler = = null from localCache according to cachekey? (List) localCache.getObject (key): null; if (list! = null) {/ / if localCache cache is found, process localOutputParameterCache handleLocallyCachedOutputParameters (ms, key, parameter, boundSql);} else {/ / look up list = queryFromDatabase (ms, parameter, rowBounds, resultHandler, key, boundSql) from the database;} finally {/ / clear the stack queryStack--;}. If (configuration.getLocalCacheScope () = = LocalCacheScope.STATEMENT) {/ / issue # 482 / / if it is STATEMENT, clear the local cache clearLocalCache ();} return list;}
Under what circumstances is it effective? Within the scope of a sqlSession on and off, so if it is hosted by Spring and no transaction is opened, then the first-level cache is invalid.
Note: open two sqlsession: sqlsession1,sqlsession2,sqlsession1.select fetches data from the first-level cache, sqlsession2 updates this data, and sqlsession1.select gets the data again, which is still in the cache.
Second-level cache
The SessionFactory layer is shared among SqlSession objects.
How to configure:
(or @ CacheNamespace), or @ CacheNamespace// each select setting
If secondary cache is configured, CachingExecutor will be returned when Executor is obtained.
/ / Configuration.java / / generate the actuator public Executor newExecutor (Transaction transaction, ExecutorType executorType) {executorType = executorType = = null? DefaultExecutorType: executorType; / / do protection again to prevent careless people from setting defaultExecutorType to null? ExecutorType = executorType = = null? ExecutorType.SIMPLE: executorType; Executor executor; / / then there are three simple branches that produce three actuators BatchExecutor/ReuseExecutor/SimpleExecutor if (ExecutorType.BATCH = = executorType) {executor = new BatchExecutor (this, transaction);} else if (ExecutorType.REUSE = = executorType) {executor = new ReuseExecutor (this, transaction);} else {executor = new SimpleExecutor (this, transaction) } / / if cache is required, generate another CachingExecutor (default is cache), decorator mode, so the default is to return CachingExecutor if (cacheEnabled) {executor = new CachingExecutor (executor);} / / call the plug-in here, through which you can change the Executor behavior executor = (Executor) interceptorChain.pluginAll (executor); return executor;}
When the second-level cache is enabled, the CachingExecutor query will be used first, and the first-level cache cannot be checked.
Public List query (MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {/ / namespace configuration function Cache cache = ms.getCache (); if (cache! = null) {/ / whether to perform cache refresh operation this.flushCacheIfRequired (ms) / / useCache tag functions if (ms.isUseCache () & & resultHandler = = null) {this.ensureNoOutParams (ms, parameterObject, boundSql); List list = (List) this.tcm.getObject (cache, key); if (list = = null) {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);}
Be careful
Because the data in the secondary cache is based on namespace, that is, the data in different namespace do not interfere with each other. If there are operations on the same table in multiple namespace, the data in these multiple namespace may be inconsistent.
In the distributed environment, because the default MyBatis Cache implementation is based on local, dirty data will inevitably be read in the distributed environment. It is necessary to use a centralized cache to implement the Cache interface of MyBatis, which has a certain development cost. It may be cheaper and more secure to directly use distributed caches such as Redis and Memcached.
Decorator mode
With decorator mode, we can add new functionality to an existing object without changing its structure.
This type of design is used for different types of caching in Mybatis.
PerpetualCache implements the Cache interface and completes the basic Cache function, which is extended by other decoration classes. Take LruCache as an example:
Public class LruCache implements Cache {/ / holds the implementation class private final Cache delegate; / / using an extra map to do lru, but there is actually a map in the delegated Cache, which is equivalent to using twice the memory to implement the lru function private Map keyMap; private Object eldestKey; public LruCache (Cache delegate) {this.delegate = delegate; setSize (1024);}.} the specific implementation of LruCache [Least Recently Used]
LruCache uses a LinkedHashMap as the keyMap, storing a maximum of 1024 key values. When a new object is added to the cache later, the infrequently used key will be removed from the keyMap and the corresponding key in the cache will be deleted. Take advantage of the features of LinkedHashMap:
Every time an element is accessed or inserted, the element is placed at the end of the linked list
/ / get method of LinkedHashMap public V get (Object key) {Node e; if ((e = getNode (hash (key), key)) = = null) return null; if (accessOrder) afterNodeAccess (e); return e.value;}
The removeEldestEntry method is called when the put,putAll method is called, so LruCache overrides the removeEldestEntry method when new LinkedHashMap
Public void setSize (final int size) {keyMap = new LinkedHashMap (size, .75F, true) {private static final long serialVersionUID = 4267176411845948333L / / the core is to override the LinkedHashMap.removeEldestEntry method. / / return true or false to tell LinkedHashMap whether to delete the oldest key value / / LinkedHashMap is to put the element at the end of the linked list every time you visit or insert an element. / / so the infrequently accessed key value must be at the beginning of the linked list @ Override protected boolean removeEldestEntry (Map.Entry eldest) {boolean tooBig = size () > size. If (tooBig) {/ / delete eldestKey = eldest.getKey ();} return tooBig;}};} private void cycleKeyList (Object key) {keyMap.put (key, key) according to eldestKey / / keyMap is linkedhashmap, the oldest record has been removed, and here we also need to remove the record if (eldestKey! = null) {delegate.removeObject (eldestKey); eldestKey = null;}} Mybatis Cache type and feature of the delegated cache.
BlockingCache: blocking version of the cache decorator, which ensures that only one thread goes to the database to find the data corresponding to the specified key. When thread A does not find the cache item corresponding to keyA in BlockingCache, thread A will acquire the lock corresponding to keyA, so that subsequent threads will block when looking for keyA.
FifoCache: first-in, first-out cache. FifoCache will put Key into a List when putObject. The length of list is 1024. If the cache is exceeded, the first cache is deleted, and the last bit is added to the current cache.
LoggingCache: log cache, which holds the log interface and can print sql and hit ratio according to log settings.
LruCache: least use of algorithms these days. The core idea is that when the cache is full, priority will be given to those caches that have been least used recently.
ScheduledCache: schedule the cache regularly. Each time you access and add the cache, you will determine whether the current time and the last cleaning time exceed the threshold. If so, the cache will be cleaned.
SerializedCache: serializes the cache. The cached value is serialized. When taking a value, it is deserialized. Requires the cached object to implement the Serializable interface.
SoftCache: soft reference cache. For an object associated with a soft reference, JVM will only recycle the object when there is insufficient memory. Using SoftReference can avoid OOM exceptions.
WeakCache: weak reference cache, similar to SoftCache. The difference from soft references is that when JVM does garbage collection, objects associated with weak references are reclaimed regardless of whether there is sufficient memory.
TransactionalCache: transaction caching
On how to understand the Mybatis source code in the Cache to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.
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.