(Rpm) MyBatis a secondary cache buffer

Cache

  Mybatis provides support for caching, but is not configured by default, it only opened a cache, a cache is only relative to a SqlSession same terms. So in SQL parameters and exactly the same situation, we use the same SqlSession Mapper object calls a method, often only once SQL, because after the first query using SelSession, MyBatis will put it in the cache, later queries next time, if there is no statement needs to be refreshed, and no cache timeout situation, SqlSession will remove the current cached data, but not sent to the SQL database again.

              

  Why use a cache, needless to say also a rough idea about. But there are several issues we should pay attention to.

  1, how long cache life cycle?

  a, MyBatis when opening a database session creates a new SqlSession objects, SqlSession object will have a new Executor object. Executor object to hold a new PerpetualCache objects; when the session ends, SqlSession object and its Executor object also PerpetualCache objects inside together also released.

  b, if SqlSession call the close () method, you can release a cache PerpetualCache object cache will not be available.

  c, such that the clearCache SqlSession call (), PerpetualCache cleans the data object, but the object can still be used.

  d, SqlSession any perform an update operation (update (), delete (), insert ()), data will be cleared PerpetualCache object, but the object can continue to use

    2, to determine how a query is exactly the same query twice?

  mybatis that, for twice the query, if the following conditions are exactly the same, then that they are exactly the same query twice.

  2.1 Incoming statementId

  2.2 query result set requirements of your results

  2.3. The inquiry eventually came to be passed to the JDBC java.sql.Preparedstatement Sql statement string (boundSql.getSql ())

  2.4 the parameter value passed to set java.sql.Statement

Secondary cache:

  MyBatis secondary cache is Application-level cache, it can improve the efficiency of database queries, to improve application performance.

  MyBatis caching mechanism and the overall design of the secondary cache operating mode

  

 

  SqlSessionFactory secondary cache on the level of default is not turned on, the secondary cache of open seats need to be configured, when implementing secondary cache, MyBatis returned POJO requirements must be serialized. Which is required to implement the Serializable interface, configuration is very simple, just open the cache can be configured in the mapping XML file <cache />, if we configured the secondary cache means:

  • All select statements in the mapped statement file will be cached.
  • The desired insert mapped statement file, update and delete statements will flush the cache.
  • Cache uses the default Least Recently Used (LRU, least recently used) algorithm for eviction.
  • According to the schedule, such as No Flush Interval, (CNFI not refresh interval), the cache will not be any sort of time to refresh.
  • The cache will store lists or objects (whatever the query method returns) of the 1024 reference
  • The cache will be treated as a read / cache write (read / write), meaning objects retrieved are not shared, and can be safely modified by the caller, the caller does not interfere with other potential modifications or threads made.

practice:

First, create a POJO Bean and serialization

  Since the secondary cache data is not necessarily stored in memory, its storage medium varied, so the object cache needs to perform serialization. (If stored in the memory, it may be found not to serialization.

package com.yihaomen.mybatis.model;

import com.yihaomen.mybatis.enums.Gender;
import java.io.Serializable;
import java.util.List;

/**
 *  @ProjectName: springmvc-mybatis 
 */
public class Student implements Serializable{

    private static final long serialVersionUID = 735655488285535299L;
    private String id;
    private String name;
    private int age;
    private Gender gender;
    private List<Teacher> teachers;

    setters&getters()....;
    toString();        
}

二、在映射文件中开启二级缓存

<?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="com.yihaomen.mybatis.dao.StudentMapper">
    <!--开启本mapper的namespace下的二级缓存-->
    <!--
        eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。
        (1) LRU,最近最少使用的,一处最长时间不用的对象
        (2) FIFO,先进先出,按对象进入缓存的顺序来移除他们
        (3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
        (4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,
                移除最长时间不用的对形象

        flushInterval:刷新间隔时间,单位为毫秒,这里配置的是100秒刷新,如果你不配置它,那么当
        SQL被执行的时候才会去刷新缓存。

        size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。
        这里配置的是1024个对象

        readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有
        办法修改缓存,他的默认值是false,不允许我们修改
    -->
    <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
    <resultMap id="studentMap" type="Student">
        <id property="id" column="id" />
        <result property="name" column="name" />
        <result property="age" column="age" />
        <result property="gender" column="gender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler" />
    </resultMap>
    <resultMap id="collectionMap" type="Student" extends="studentMap">
        <collection property="teachers" ofType="Teacher">
            <id property="id" column="teach_id" />
            <result property="name" column="tname"/>
            <result property="gender" column="tgender" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
            <result property="subject" column="tsubject" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
            <result property="degree" column="tdegree" javaType="string" jdbcType="VARCHAR"/>
        </collection>
    </resultMap>
    <select id="selectStudents" resultMap="collectionMap">
        SELECT
            s.id, s.name, s.gender, t.id teach_id, t.name tname, t.gender tgender, t.subject tsubject, t.degree tdegree
        FROM
            student s
        LEFT JOIN
            stu_teach_rel str
        ON
            s.id = str.stu_id
        LEFT JOIN
            teacher t
        ON
            t.id = str.teach_id
    </select>
    <!--可以通过设置useCache来规定这个sql是否开启缓存,ture是开启,false是关闭-->
    <select id="selectAllStudents" resultMap="studentMap" useCache="true">
        SELECT id, name, age FROM student
    </select>
    <!--刷新二级缓存
    <select id="selectAllStudents" resultMap="studentMap" flushCache="true">
        SELECT id, name, age FROM student
    </select>
    -->
</mapper>

三、在 mybatis-config.xml中开启二级缓存

<?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>
        <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存-->
        <setting name="cacheEnabled" value="true" />
        .....
    </settings>
    ....
</configuration>

四、测试

package com.yihaomen.service.student;

import com.yihaomen.mybatis.dao.StudentMapper;
import com.yihaomen.mybatis.model.Student;
import com.yihaomen.mybatis.model.Teacher;
import com.yihaomen.service.BaseTest;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;

/**
 *   
 *  @ProjectName: springmvc-mybatis 
 */
public class TestStudent extends BaseTest {

    public static void selectAllStudent() {
        SqlSessionFactory sqlSessionFactory = getSession();
        SqlSession session = sqlSessionFactory.openSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Student> list = mapper.selectAllStudents();
        System.out.println(list);
        System.out.println("第二次执行");
        List<Student> list2 = mapper.selectAllStudents();
        System.out.println(list2);
        session.commit();
        System.out.println("二级缓存观测点");
        SqlSession session2 = sqlSessionFactory.openSession();
        StudentMapper mapper2 = session2.getMapper(StudentMapper.class);
        List<Student> list3 = mapper2.selectAllStudents();
        System.out.println(list3);
        System.out.println("第二次执行");
        List<Student> list4 = mapper2.selectAllStudents();
        System.out.println(list4);
        session2.commit();

    }

    public static void main(String[] args) {
        selectAllStudent();
    }
}

 

Guess you like

Origin www.cnblogs.com/cat520/p/11198885.html