From getting started to giving up MyBatis 7: Analysis on the principle of second-level cache, mybatis second-level cache

Source: Internet
Author: User

From getting started to giving up MyBatis 7: Analysis on the principle of second-level cache, mybatis second-level cache
Preface

Speaking of the level-1 cache and level-2 cache of mybatis, I specifically asked a few friends around me if they would normally use it. As a result, no one is usually using it in business scenarios. Well, I will use it to learn the source code for the moment. I personally think that the level-1 cache is indeed a little tricky. mybatis enables the level-1 cache by default and supports two executions of the same statement in the same session (sqlsession, the cache object created for the first time will be used by default for the second time.

A rough introduction to the second-level cache section describes how to use the Memory Object PerpetualCache to internally maintain a HashMap object for storage by default. Let's take a look at a few pictures first. [the picture is from a friend. I will post my author's blog after the final reference of the article]

 

MyBatis Cache Design and second-level cache Working Mode

From the above three figures, we can conclude that the first-level cache is at the sqlsession level and the second-level cache is at the Mapper level. Mybatis defines the [Cache] interface, supports custom caching, and also supports integration with third-party Cache libraries. to better control the Cache, more integration [ehcache] and [redis ].

Therefore, the second-level cache of mybatis is mainly written on the Executor object. When mybatis finds that you are in mybatis. when cacheEnabled = true is set in the xml configuration file, mybatis creates the Executor object when creating the sqlsession, and adds the modifier CacheExecutor to the Executor ]. CacheExecutor determines whether the application-level second-level cache has cached results for query requests. If there is a query result, it will return directly. If it is not submitted to the queryexecutor implementation class, that is, SimpleExecutor is used to execute the query. Then the cache result is returned to the user.

Paste the SmpleExecutor source code:

/** *    Copyright 2009-2016 the original author or authors. * *    Licensed under the Apache License, Version 2.0 (the "License"); *    you may not use this file except in compliance with the License. *    You may obtain a copy of the License at * *       http://www.apache.org/licenses/LICENSE-2.0 * *    Unless required by applicable law or agreed to in writing, software *    distributed under the License is distributed on an "AS IS" BASIS, *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *    See the License for the specific language governing permissions and *    limitations under the License. */package org.apache.ibatis.executor;import org.apache.ibatis.cursor.Cursor;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.logging.Log;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.apache.ibatis.transaction.Transaction;import java.sql.Connection;import java.sql.SQLException;import java.sql.Statement;import java.util.Collections;import java.util.List;/** * @author Clinton Begin */public class SimpleExecutor extends BaseExecutor {  public SimpleExecutor(Configuration configuration, Transaction transaction) {    super(configuration, transaction);  }  @Override  public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {    Statement stmt = null;    try {      Configuration configuration = ms.getConfiguration();      StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);      stmt = prepareStatement(handler, ms.getStatementLog());      return handler.update(stmt);    } finally {      closeStatement(stmt);    }  }  @Override  public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {    Statement stmt = null;    try {      Configuration configuration = ms.getConfiguration();      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);      stmt = prepareStatement(handler, ms.getStatementLog());      return handler.<E>query(stmt, resultHandler);    } finally {      closeStatement(stmt);    }  }  @Override  protected <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql) throws SQLException {    Configuration configuration = ms.getConfiguration();    StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, null, boundSql);    Statement stmt = prepareStatement(handler, ms.getStatementLog());    return handler.<E>queryCursor(stmt);  }  @Override  public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException {    return Collections.emptyList();  }  private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {    Statement stmt;    Connection connection = getConnection(statementLog);    stmt = handler.prepare(connection, transaction.getTimeout());    handler.parameterize(stmt);    return stmt;  }}

So how does the cached data expire? This is my focus in this article. Generally, sites with low traffic are maintained by the backend, and the second-level cache is sufficient. Let's take a look at the global configuration file. The configuration is only concerned with cacheEnabled = true.

<? Xml version = "1.0" encoding = "UTF-8"?> <! DOCTYPE configuration PUBLIC "-// mybatis.org//DTD Config 3.0 // EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <! -- Enable Level 2 Cache --> <setting name = "cacheEnabled" value = "true"/> </settings> <typeAliases> <typeAlias alias = "User" type = "com. autohome. model. user "/> </typeAliases> <mappers> <mapper resource =" mapper/UserMapper. xml "/> </mappers> </configuration>

Mapper. xml

Configure the Cache object here. The eviction parameter here mentions several algorithm strategies:

LRU :( Least Recently Used)The algorithm is used at least recently. That is, if the cache capacity is full, the recently used cache records in the cache will be cleared and new records will be added;

FIFO :( First in first out), First-in-first-out algorithm. If the cache capacity is full, the data first enters the cache will be cleared;

Scheduled: Clears the algorithm at a specified interval.CacheData in the cache is cleared;

<? Xml version = "1.0" encoding = "UTF-8"?> <! DOCTYPE mapper PUBLIC "-// mybatis.org//DTD Mapper 3.0 //" http://mybatis.org/dtd/mybatis-3-mapper.dtd "> <! -- The namespace and interface must be consistent --> <mapper namespace = "com. autohome. dao. UserMapper"> <! -- Eviction LRU flushInterval cache time, in milliseconds, the size of the cache readOnly. If it is false, the cache object must be serializable --> <cache eviction = "LRU" type = "org. apache. ibatis. cache. impl. perpetualCache "flushInterval =" 120000 "size =" 1024 "readOnly =" true "/> <select id =" listAllUser "resultType =" User "> select * from t_userinfo </select> </mapper>

 

View demo with a picture

The first query is 36 data records, and I configured the cache to be 2 minutes. Then insert a record, and refresh the page again without changing the data. Wait for two minutes ....

 

Summary

OK, the so-called existence is reasonable. It is not suitable for your business scenarios. Mybatis also provides interfaces for extension. The use of mybatis second-level cache is sufficient for small traffic and small data volumes.

 

Reference

Http://blog.csdn.net/luanlouis/article/details/41408341

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.