MyBatis is that simple

Keywords: Programming Mybatis SQL JDBC Ehcache

0. Introduction to MyBatis

1) MyBatis is an open source Apache project iBatis, which was migrated to Google Code by Apache Software Foundation in June 2010. As the development team moved to Google Code, iBatis 3.x was officially renamed MyBatis and the code was migrated to Github in November 2013

2) The term iBatis comes from a combination of "internet" and "abatis", which is a persistent Java-based framework.IBatis provides a persistence layer framework that includes SQL Maps and Data Access Objects (DAO)

Download Web Site

         https://github.com/mybatis/mybatis-3/

Why use MyBatis - a comparison of existing persistence technologies

  1. JDBC
  • SQL clipped in Java code block, high coupling causes hard-coded internal injury
  • Maintenance is not easy and sql changes in actual development requirements, frequent modifications are common

2.Hibernate and JPA

  • Long and complex SQL, not easy for Hibernate
  • Internal auto-produced SQL, not easy to do special optimization
  • Based on the fully automatic framework of full mapping, partial mapping of POJO s with a large number of fields is difficult.Cause database performance degradation

3.MyBatis

  • Core sql still needs to be optimized for developers
  • Separate sql and java encoding, clear functional boundaries, one focused business, one focused data

1.MyBatis HelloWorld

1. jar package for importing MyBatis framework, Mysql driver package, jar package for log4j

  • myBatis-3.4.1.jar
  • mysql-connector-java-5.1.37-bin.jar
  • log4j.jar

2. Import log4j.xml configuration file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
   <param name="Encoding" value="UTF-8" />
   <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
   </layout>
 </appender>
 <logger name="java.sql">
   <level value="debug" />
 </logger>
 <logger name="org.apache.ibatis">
   <level value="info" />
 </logger>
 <root>
   <level value="debug" />
   <appender-ref ref="STDOUT" />
 </root>
</log4j:configuration>

3. Create test tables

-- Create Library
CREATE DATABASE test_mybatis;
-- Using Libraries
USE test_mybatis;
-- Create Table
CREATE TABLE tbl_employee(
   id INT(11) PRIMARY KEY AUTO_INCREMENT,
   last_name VARCHAR(50),
   email VARCHAR(50),
   gender CHAR(1)
);

4. Create a javaBean

public class Employee {

	private Integer id ; 
	private String lastName; 
	private String email ;
	private String gender ;
	public Integer getId() {
		return id;
	}
	//...to generate get, set, toString
	}

5. Create myBatis global profile (refer to the official website manual)

<?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>
	<!-- Configuration of database connection environment -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis_1129" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	<!-- Introduce SQL Mapping File,Mapper Mapping File 	-->
	<mappers>
		<mapper resource="EmployeeMapper.xml" />
	</mappers>
</configuration>

6. Create a Mapr Mapping File for Mybatis

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="suibian">
	<select id="selectEmployee" resultType="com.hbuas.myabtis.helloWorld.Employee">
		select id ,last_name lastName ,email ,gender from tbl_employee where id = #{id}
		<!-- select * from tbl_employee  where id = #{id} -->
	</select>
</mapper>

7. Write test classes

@Test
	public void test() throws Exception {
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = 
					new SqlSessionFactoryBuilder().build(inputStream);
		System.out.println(sqlSessionFactory);
		
		SqlSession session  = sqlSessionFactory.openSession();
		try {
			Employee employee = 
					session.selectOne("suibian.selectEmployee", 1001);
			System.out.println(employee);
		} finally {
			session.close();
		}
	}

Mapper Interface Development MyBatis HelloWorld

Using mapper interface development is Interface-oriented programming advocated by Mybatis

1. Write a Mapper interface to implement two bindings:

  • The fully qualified name of the interface should match the namespace of the mapping file
  • The method name in the interface is identical to the ID of the SQL statement
public interface EmployeeMapper {
	
	public Employee getEmployeeById(Integer id );	
	
}

3. Write test classes

Get the session object SqlSession of the Mybatis operation database, and implement the class by getMapper() to get the dynamic proxy of the interface

@Test
public void test()  throws Exception{
	String resource = "mybatis-config.xml";
	InputStream inputStream =
        Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory = 
				new SqlSessionFactoryBuilder()
              .build(inputStream);		
	SqlSession session = 
                         sqlSessionFactory.openSession();
		
		try {
			//Mapper interface: A proxy implementation class object that obtains the Mapper interface
			EmployeeMapper mapper =
                 session.getMapper(EmployeeMapper.class);		
			Employee employee = 
                  mapper.getEmployeeById(1006);
			System.out.println(employee);
		} finally {
			session.close();
		}
	}

3.Mybatis Profile

The configuration file for MyBatis contains settings and properties information that deeply affect the behavior of MyBatis.

The configuration file is structured as follows:

configuration Configuration
Properrties property
settings Settings
TypeeAliases Type Naming
TypeeHandlers Type Processor
objectFactory Object Factory
plugins
Environment Environment
Environment environment variables
Transaction Manager Transaction Manager
Data Source Data Source
Database vendor identification for databaseIdProvider
mappers Mapper

 

Attribute information is configured strictly in the order above.

properties attribute

  1. Externally configurable and dynamically replaceable, either in a typical Java property file or through child elements of the properties element
    <properties>
         <property name="driver" value="com.mysql.jdbc.Driver" />
         <property name="url" 
                 value="jdbc:mysql://localhost:3306/test_mybatis" />
         <property name="username" value="root" />
         <property name="password" value="1234" />
     </properties>
    

Properrties does more than that. You can create a resource file, named jdbc.properties, that places four connection strings of data in the resource file as key = value pairs, with no symbols and one on a line

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_1129
jdbc.username=root
jdbc.password=1234

 

<!-- 
	properties:Introduce an external property file
	resource: Introduce a property file from the class path 
	url: Introduce a network path or a property file under a disk path
-->
<properties resource="db.properties" ></properties>
<environments default="oracle">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" 
                         value="${jdbc.username}" />
				<property name="password" 
                         value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>

settings Settings

  1. These are extremely important adjustment settings in MyBatis that change the runtime behavior of MyBatis.
  2. Contains setting s as follows:
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>Turn on delayed loading
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>Map underscores to humps
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods"
           value="equals,clone,hashCode,toString"/>
</settings>

typeAliases

1. Type aliases are short names for Java types that make it easy for us to reference a class.

<typeAliases>
      <typeAlias type="com.hbuas.mybatis.beans.Employee" alias="emp"/>
</typeAliases>

The alias attribute can be case-insensitive, and the default is that class names are case-insensitive.

2. In cases where there are many classes, you can set aliases in batches. Each class under this package can create a default alias, which is a simple class name in lower case.

<typeAliases>
      <package name="com.hbuas.mybatis.beans"/>
</typeAliases>

Environment Configuration

  1. MyBatis can be configured in a variety of environments, such as development, testing, and production environments that require different configurations
  2. Each environment is configured with an environment tag and a unique identifier is specified
  3. You can quickly switch environments by specifying an environment identifier with the default attribute in the environments tag
  4. Environment-Specify specific environment
    • id: Specifies the unique identity of the current environment
    • Both transactionManager and dataSource must have

 

<environments default="oracle">
		<environment id="mysql">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
		 <environment id="oracle">
			<transactionManager type="JDBC"/>	
			<dataSource type="POOLED">
				<property name="driver" value="${orcl.driver}" />
				<property name="url" value="${orcl.url}" />
				<property name="username" value="${orcl.username}" />
				<property name="password" value="${orcl.password}" />
			</dataSource>
		</environment> 
		
	</environments>

4.MyBatis Mapping File

  1. The real power of MyBatis is its mapping statement, and its magic.Because of its power, the mapper's XML file is relatively simple.If you compare it to JDBC code with the same functionality, you'll immediately see that almost 95% of the code has been omitted.MyBatis is built for SQL and does a better job than the usual methods.
  2. The SQL mapping file has few top-level elements (in the order in which they should be defined):

cache - cache configuration for a given namespace.

cache-ref - Reference to other namespace cache configurations.

resultMap - The most complex and powerful element that describes how to load objects from a database result set.

parameterMap - obsolete!Old style parameter mapping.Inline parameters are preferred, and this element may be removed in the future and will not be recorded here.

sql - A reusable statement block that can be referenced by other statements.

Insert-map insert statement

update - Map update statement

Delete - Map delete statement

select - map query

Complete CRUD using insert|update|delete|select

  1. Mapper interface method
    public interface EmpMapper {
    
    	//Query an employee based on eid
    	Emp getEmpByEid(String eid);
    	//Get all employee information
    	List<Emp> getAllEmp();
    	//Add employee information
    	void addEmp(Emp emp);
    	//Modify employee information
    	void updateEmp(Emp emp);
    	//Delete employee information
    	Boolean deleteEmp(String eid);
    	
    }
  2. Mapper Mapping File
    <mapper namespace="com.hbuas.mapper.EmpMapper">
    	
    	<!-- Emp getEmpByEid(String eid); -->
    	<select id="getEmpByEid" resultType="Emp">
    		select eid,ename,age,sex from emp where eid = #{eid}
    	</select>
    	
    	<!-- List<Emp> getAllEmp(); -->
    	<select id="getAllEmp" resultType="Emp">
    		select eid,ename,age,sex from emp
    	</select>
    	
    	<!-- void addEmp(Emp emp); -->
    	<insert id="addEmp">
    		insert into emp values(null,#{ename},#{age},#{sex})
    	</insert>
    	
    	<!-- void updateEmp(Emp emp); -->
    	<update id="updateEmp">
    		update emp set ename = #{ename}, age = #{age}, sex = #{sex} where eid = #{eid}
    	</update>
    	
    	<!-- void deleteEmp(String eid); -->
    	<delete id="deleteEmp">
    		delete from emp where eid = #{eid}
    	</delete>
    	
    </mapper>

    Primary Key Generation, Get Primary Key Value

Get Primary Key Value

  1. If the database supports fields that automatically generate primary keys (such as MySQL and SQL Server), you can set useGeneratedKeys="true" and then set keyProperty on the target property.
    <insert id="insertEmployee" 	parameterType="com.hbuas.mybatis.beans.Employee"  
    	databaseId="mysql"  useGeneratedKeys="true"  keyProperty="id">
        insert into tbl_employee(last_name,email,gender) values(#{lastName},#{email},#{gender})
    </insert>
    
  2. For databases that do not support self-increasing primary keys, such as Oracle, you can use the selectKey subelement: the selectKey element will run first, the id will be set, and the insert statement will be called
    <insert id="insertEmployee" 
    		parameterType="com.atguigu.mybatis.beans.Employee"  
    			databaseId="oracle">
    		<selectKey order="BEFORE" keyProperty="id" 
                                           resultType="integer">
    			select employee_seq.nextval from dual 
    		</selectKey>	
    		insert into orcl_employee(id,last_name,email,gender) values(#{id},#{lastName},#{email},#{gender})
    </insert>
    

    Parameter Transfer

myBatis obtains parameter values in two ways:

  • ${}
    • insert into emp values(null,admin,23, male)
    • Statement: SQL must be manipulated using string splicing
  • #{}
    • insert into emp values(null,?,?,?)
    • PrepareStatement: You can use wildcards to manipulate SQL;

How parameters are passed

1. Single common type parameter: can accept basic type, wrapper type, string type, etc.

  • #{}: Parameter values can be obtained under any name
  • ${}: only available in ${value}, ${parameter}

2. Multiple parameters

Any number of parameters will be repackaged by MyBatis as a Map and passed in.Map's key is param1, param2, or 0, 1...Value is the value of the parameter

#{}:#{0},#{1},#{param1},#{param2}

${}:${value}, ${param2}, but note the single quotation mark problem of ${}

3. Named parameters

Use for parameters @Param Once a name is given, MyBatis encapsulates these parameters in a map, and key is the name we specify.Both #{}, ${} can get a value by the health name, note the single quotation mark problem.

4.POJO

When these parameters belong to our business POJO, we pass the POJO property name directly to get the value, but note the ${} single quotation mark problem.

5.Map

We can also encapsulate multiple parameters as map s and pass them directly

6.Collection/Array

Encapsulated by MyBatis into a map, List with list as key, Array with array as key

Automatic and Custom Mapping

  • resultType automatic mapping
    • The default is to turn on automatic mapping.The only requirement is that the result set column names match the javaBean property names.
    • If autoMappingBehavior is set to null, the automap is cancelled
  • resultMap custom mapping
	<!-- 
		<resultMap>: Customize mappings to handle complex table relationships
		<id column="eid" property="eid"/>
		<id>: set the mapping relationship of the primary key, column set the field name, property set the property name
		<result column="ename" property="ename"/>
		<result>: Set mapping relationships for non-primary keys, column set field names, and property set property names
	 -->
 	<!-- This method is less useful-->
       <resultMap type="Emp" id="empMap">
		<id column="eid" property="eid"/>
		<result column="ename" property="ename"/>
		<result column="age" property="age"/>
		<result column="sex" property="sex"/>
		<result column="did" property="dept.did"/>
		<result column="dname" property="dept.dname"/>
	</resultMap> 

<!-- List<Emp> getAllEmp(); -->
<select id="getAllEmp" resultMap="empMap">
	select e.eid,e.ename,e.age,e.sex,e.did,d.dname from emp e left join dept d on e.did = d.did
</select>
	

association

Encapsulate objects in a cascade of attributes.

	<resultMap type="Emp" id="empMap">
		<id column="eid" property="eid"/>
		<result column="ename" property="ename"/>
		<result column="age" property="age"/>
		<result column="sex" property="sex"/>
		<association property="dept" javaType="Dept">
			<id column="did" property="did"/>
			<result column="dname" property="dname"/>
		</association>
	</resultMap>

association step-by-step query

  1. In the actual development, there should be specific ways to add or delete changes to each entity class, that is, the DAO layer, so the query can be completed step by step for the need to query employee information and the corresponding department information.
  • Query employee information through employee id first
  • Then the corresponding department information is queried by the foreign key (department id) in the queried employee information.
<select id="getEmployeeAndDeptStep" resultMap="myEmpAndDeptStep">
		 select id, last_name, email,gender,d_id  from tbl_employee where id =#{id}
</select>
	

<resultMap type="com.hbuas.mybatis.beans.Employee" id="myEmpAndDeptStep">
		<id column="id"  property="id" />
		<result column="last_name" property="lastName"/>
		<result column="email" property="email"/>
		<result column="gender" property="gender"/>
		<association property="dept"
                 select="com.hbuas.mybatis.dao.DepartmentMapper.getDeptById" 
				column="d_id" fetchType="eager">
		</association>
</resultMap>
  • On the basis of step-by-step queries, delayed loading can be used to improve query efficiency, requiring only global

The following configuration is done in Settings:

<!--Turn on delayed loading-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--Set whether the loaded data is on demand or all-->
<setting name="aggressiveLazyLoading" value="false"/>

collection

Specially designed to handle one-to-many and many-to-many relationships

  1. Attributes in POJO may be a collection object, and we can use joint queries to encapsulate objects in a cascading manner. Use collection tags to define encapsulation rules for objects
    	<resultMap type="Dept" id="deptMap">
    		<id column="did" property="did"/>
    		<result column="dname" property="dname"/>
    		<!-- 
    			<collection>:Handling one-to-many and many-to-many relationships
    			ofType: Refers to a type in a collection that does not need to be specified javaType
    		 -->
    		<collection property="emps" ofType="Emp">
    			<id column="eid" property="eid"/>
    			<result column="ename" property="ename"/>
    			<result column="age" property="age"/>
    			<result column="sex" property="sex"/>
    		</collection>
    	</resultMap>

    collection step-by-step query

  1. In the actual development, there should be a specific way to add or delete changes to each entity class, that is, the DAO layer, so

For the requirement of querying department information and also querying all corresponding employee information, the query can be completed step by step.

  • Inquire department information through Department id first
  • Then query the corresponding department information through the Department id as the foreign key of the employee.
	<!-- List<Emp> getEmpListByDid(String did); -->
	<select id="getEmpListByDid" resultType="Emp">
		select eid,ename,age,sex from emp where did = #{did}
	</select>
	
	<resultMap type="Dept" id="deptMapStep">
		<id column="did" property="did"/>
		<result column="dname" property="dname"/>
		<collection property="emps" select="com.hbuas.mapper.EmpDeptMapper.getEmpListByDid" column="{did=did}" fetchType="eager"></collection>
	</resultMap>
	
	<!-- Dept getOnlyDeptByDid(String did); -->
<select id="getOnlyDeptByDid" resultMap="deptMapStep">
	select did,dname from dept where did = #{did}
</select>

1. You can set fetchType in both <association>and <collection>tags to specify whether this query will use delayed loading.The default is fetchType="lazy". If this query does not want to use delayed loading, it can be set to fetchType="eager".

2.fetchType provides flexibility in setting whether queries need to use delayed loading rather than turning off global delayed loading settings because a query does not want to use delayed loading.

5.MyBatis Dynamic SQL

Introduction to MyBatis Dynamic SQL

  1. Dynamic SQL is one of the powerful features of MyBatis.Greatly simplifies how we assemble SQL
  2. Dynamic SQL elements are similar to using JSTL or other XML-based text processors
  3. MyBatis uses powerful OGNL-based expressions to simplify operations

if  where

  1. If is used to make simple judgments.
  2. Where is used to solve where keywords in SQL statements and the first and or in a condition
	<select id="getEmpListByMoreTJ1" resultType="Emp">
		select eid,ename,age,sex,did from emp 
		<where>
			<if test="eid != null">
				and eid = #{eid}
			</if>
			<if test="ename != null and ename != ''">
				and ename = #{ename}
			</if>
			<if test="age != null">
				and age = #{age}
			</if>
			<if test="sex == 1 or sex == 0">
				and sex = #{sex}
			</if>
		</where>
	</select>

trim

  1. Trim can add or remove specified characters before and after a conditional SQL statement
  • prefix: Add something before the SQL statement of the operation
  • prefixOverrides: Remove a line before the SQL statement of the operation
  • suffix: Add something before the SQL statement of the operation
  • suffixOverrides: Remove a line before the SQL statement of the operation
	<select id="getEmpListByMoreTJ1" resultType="Emp">
		select eid,ename,age,sex,did from emp 
		<trim prefix="where"  suffixOverrides="and">
			<if test="eid != null">
				eid = #{eid} and 
			</if>
			<if test="ename != null and ename != ''">
				ename = #{ename}and 
			</if>
			<if test="age != null">
				age = #{age}and 
			</if>
			<if test="sex == 1 or sex == 0">
				sex = #{sex}
			</if>
		</where>
	</select>

set

set is primarily used to solve the problem of possible commas in SQL statements during modification operations

<update id="updateEmpByConditionSet">
		update  tbl_employee  
		<set>
			<if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
				 last_name = #{lastName},
			</if>
			<if test="email!=null and email.trim()!=''">
				 email = #{email} ,
			</if>
			<if test="&quot;m&quot;.equals(gender) or &quot;f&quot;.equals(gender)">
				gender = #{gender} 
			</if>
		</set>
		 where id =#{id}
</update>

choose(when,otherwise)

choose is primarily used for branch judgment, similar to switch case s in java, where only one of all branches is satisfied

<select id="getEmpsByConditionChoose" resultType="com.hbuas.mybatis.beans.Employee">
		select id ,last_name, email,gender from tbl_employee
		<where>
			<choose>
				<when test="id!=null">
					id = #{id}
				</when>
				<when test="lastName!=null">
					last_name = #{lastName}
				</when>
				<when test="email!=null">
					email = #{email}
				</when>
				<otherwise>
					 gender = 'm'
				</otherwise>
			</choose>
		</where>
</select>

foreach

<!-- 
	<foreach collection="" item="" close="" open="" separator="" index=""></foreach>
	Traverse an array or set
	Collection: Specifies the collection or array to traverse
	item: set alias
	close: Sets the end of the loop body
	open: Set the beginning of the loop
	Separator: set the separator between each loop
	Index: if a list is traversed, index represents the subscript; if a map is traversed, index represents the key
	 -->
<delete id="deleteMoreByList">
	delete from emp where eid in 
	<foreach collection="eids" item="eid" separator="," open="(" close=")">
		#{eid}
	</foreach>
</delete>

sql

The sql tag is used to extract reusable sql fragments, which are the same and frequently used sql fragments, and can be defined separately for multiple references.

<!-- 
	<sql id="></sql>: Set a SQL fragment, the public SQL, that can be accessed by all the SQL statements in the current mapping file
	<include refid="empColumns"></include>: Access a SQL fragment
 -->


<sql id="empColumns">select eid,ename,age,sex,did from emp </sql>


<select id="getEmpByEid" resultType="Emp">
		<include refid="empColumns"></include> where eid = #{eid}
</select>

6.MyBatis Cache Mechanism

MyBatis includes a very powerful query cache feature that can be easily configured and customized.Caching can greatly improve query efficiency. By default, MyBatis defines two levels of caching (first-level caching, second-level caching). By default, only one level of caching (SqlSession-level caching, also known as local caching) is turned on.

  1. Second-level caches need to be manually turned on and configured; they are namespace-based caches.
  2. To improve scalability.MyBatis defines the cache interface Cache.We can customize the secondary cache by implementing the Cache interface

Use of Level 1 Cache

/**
The first level cache in mybatis is turned on by default, at the SqlSession level
	That is, the same SqlSession for a sql statement is stored in the cache after execution, the next time the same sql is executed, it is fetched directly from the cache
          

  When the first level cache fails:
		 *Different SqlSession s correspond to different first-level caches
		 *Same SqlSession but different query conditions
		 *Any addition or deletion during the same SqlSession query automatically empties the cache
		 *The cache was manually emptied during the same SqlSession query twice
*/

Use of secondary cache

/**
 * The secondary cache for mybatis is not enabled by default and needs to be set:
         * 1. In the core profile <settings>, add the configuration: <setting name="cacheEnabled" value="true"/>
         * 2. Use cache to configure cache <cache /> where mapping files need to use secondary cache
         * 3. Note: POJO needs to implement Serializable interface
         *Note: The secondary cache will not take effect until SqlSession is closed or submitted
   
      * 1) cacheEnable for global setting s:
            Configure the switch for the secondary cache, which is always on
         * 2) The useCache attribute of the select tag:
            Configure whether this select uses a secondary cache.Level 1 cache is always used
         * 3) flushCache attribute of SQL tag:
            Add or delete the default flushCache=true.After sql executes, both primary and secondary caches are cleared.
            Query default flushCache=false.
         * 4)sqlSession.clearCache(): used only to clear the first level cache
         */

Secondary Cache Related Properties

  • eviction="FIFO": Cache Recycling Policy:

LRU - least recently used: removes objects that have not been used for the longest time.

FIFO - FIFO: Remove objects in the order they enter the cache.

SOFT - Soft Reference: Remove objects based on garbage collector status and soft reference rules.

WEAK - Weak References: Actively remove objects based on garbage collector status and weak reference rules.

The default is LRU.

  • flushInterval: Refresh interval in milliseconds

By default, there is no refresh interval, and the cache refreshes only when the statement is invoked

  • size: number of references, positive integer

Represents the maximum number of objects a cache can store, which is too large to cause memory overflow

  • readOnly: Read-only, true/false

true: read-only cache; returns the same instance of the cache object to all callers.Therefore, these objects cannot be modified.This provides important performance advantages.

False: read-write cache; returns a copy of the cache object (by serialization).This is slower, but safe, so it defaults to false.

Cache-related property settings

  1. cacheEnable for global setting s: Configure the switch for the secondary cache, which is always open.
  2. SelectTag useCache property: Configure whether this select uses a secondary cache.Level 1 cache is always used
  3. FlushCache property of sql tag: Add or delete default flushCache=true.After sql executes, both primary and secondary caches are cleared.Query default flushCache=false.
  4. sqlSession.clearCache(): Used only to clear the first level cache.

Integrating third-party caches

To improve scalability.MyBatis defines the cache interface Cache.We can customize the secondary cache by implementing the Cache interface

EhCache is a Java-only in-process cache framework that is fast, compact, and the default CacheProvider in Hibernate

Steps to integrate EhCache caches

1. Import ehcache packages, as well as consolidation packages, log packages

  • ehcache-core-2.6.8.jar
  • mybatis-ehcache-1.0.3.jar
  • slf4j-api-1.6.1.jar,slf4j-log4j12-1.6.2.jar

2. Write ehcache.xml configuration file

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- Disk Save Path -->
 <diskStore path="D:\hbuas\ehcache" />
 
 <defaultCache 
   maxElementsInMemory="1000" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
 
<!-- 
//Property description:
l diskStore: Specifies where the data is stored on disk.
l defaultCache: When using CacheManager.add("demoCache")Establish Cache When, EhCache Will use<defalutCache/>Specified Management Policy
 
//The following attributes are required:
l maxElementsInMemory - Cached in memory element Maximum number 
l maxElementsOnDisk - Cached on disk element Maximum number if 0 means infinity
l eternal - Set Cached elements Will it never expire?If is true,The cached data is always valid if it is false Then also depend on timeToIdleSeconds,timeToLiveSeconds judge
l overflowToDisk - Set whether the memory cache will expire when it overflows element Cache on disk
 
//The following properties are optional:
l timeToIdleSeconds - When cached in EhCache Data in has been accessed more than twice before timeToIdleSeconds The data is deleted when an attribute of 0 is selected, and the default value is 0.,That is, the idle time is infinite
l timeToLiveSeconds - cache element Valid lifetime, default is 0.,that is element Lifetime is infinite
 diskSpoolBufferSizeMB This parameter setting DiskStore(Disk Cache)Cache size of.Default is 30 MB.each Cache All should have their own buffer.
l diskPersistent - stay VM Whether disk save is enabled on restart EhCache Data in, default is false. 
l diskExpiryThreadIntervalSeconds - Disk cache cleanup thread run interval, default is 120 seconds.Each 120 s,The corresponding thread will run once EhCache Cleaning up data in
l memoryStoreEvictionPolicy - When the memory cache reaches its maximum, there is a new element Remove cache when joining element Strategy for.Default is LRU(Least recently used), optional LFU(Least frequently used) and FIFO(FIFO)
 -->

3. Configure cache tags

<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

Posted by nsantos on Fri, 14 Feb 2020 10:12:52 -0800