Mybatis二级缓存的简单应用

1.接口

public interface MemberMapperCache {

    public Members selectMembersById(Integer id);
    
}

2.POJO类

实现序列化接口

public class Members implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String member_name;

    private Integer age;

    private Integer gender;

    private String email;

    public Members() {}

    public Members(Integer id, String member_name, Integer age, Integer gender, String email) {
        super();
        this.id = id;
        this.member_name = member_name;
        this.age = age;
        this.gender = gender;
        this.email = email;
    }

    public Integer getId() {
        return id;
    }

    public String getMember_name() {
        return member_name;
    }

    public Integer getAge() {
        return age;
    }

    public Integer getGender() {
        return gender;
    }

    public String getEmail() {
        return email;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setMember_name(String member_name) {
        this.member_name = member_name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Members [id=" + id + ", member_name=" + member_name + ", age=" + age + ", gender=" + gender + ", email=" + email + "]";
    }
    
}

3.mapper.xml配置

<?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.dao.MemberMapperCache">
    <!-- 
        eviction:缓存的回收策略
            LRU:最近最少使用的,移除最长时间不被使用的对象
            FIFO:先进先出,按对象进入缓存的顺序来移除他们
            SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象
            WEAK:弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象
            默认是LRU
        flushInterval:缓存刷新间隔
            默认不清空
        readOnly:是否只读
            true:只读:mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据
                mybatis为了加快获取速度,直接将数据在缓存中的引用交给用户,不安全,但是速度快
            false:非只读:mybatis觉得获取的数据可能会被修改,并会用序列化和反序列化技术克隆一份新的数据
                再给用户,这样安全,但是速度相对慢
                默认false,非只读
        size:缓存中存放多少个元素
        type:自定义缓存,实现Cache接口集合,type="全类名"
        
        ===>POJO必须实现序列化接口
     -->

    <cache eviction="LRU" flushInterval="60000" readOnly="false" size="1024"></cache>
    
    <select id="selectMembersById" resultType="members">
    
        select * from members where id = #{id}
        
    </select>

</mapper>

4.全局配置文件

开启二级缓存和日志打印

    <settings>  
        <!-- 打印log日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/> 
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/> 
    </settings>

5.测试类

    /**
     * Mybatis的缓存机制
     * 二级缓存:
     *         1.在全局配置文件中开启二级缓存
     *         2.在mapper.xml文件中加入<cache><cache/>标签
     *         3.POJO实现序列化接口
     */
    public static void main(String[] args) throws IOException {
        // 获取两个不同的session
        SqlSession session1 = getSqlSession();
        SqlSession session2 = getSqlSession();
        try {
            // 获取两个不同的mapper
            MemberMapperCache mapper1 = session1.getMapper(MemberMapperCache.class);
            MemberMapperCache mapper2 = session2.getMapper(MemberMapperCache.class);
            // 获取id为1的对象
            Members member1 = mapper1.selectMembersById(1);
            System.out.println(member1.toString());
            session1.close();
            // 获取id为1的对象
            Members member2 = mapper2.selectMembersById(1);
            System.out.println(member2.toString());
            session2.close();
        } finally {
            
        }
    }

    public static SqlSession getSqlSession() throws IOException {
        // 读取全局配置文件
        String resource = "conf/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 获取sqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 打开session
        SqlSession session = sqlSessionFactory.openSession();
        return session;
    }

mybatis的二级缓存是namespace级别的缓存,也就是mapper级别的缓存,则mapper中所有的select语句默认都将被缓存,此命名空间下所有insert、update、delete语句将会导致空间下的缓存被清空

在单表操作的情况下用二级缓存是没什么问题的,但是在多关联中,用二级缓存就存在很大的风险,这里我百度搜了一下,有好多栗子,就不列举了,原链接是   https://www.cnblogs.com/liouwei4083/p/6025929.html

还是不推荐是用mybatis自带的缓存机制,还是在业务层用自己能控制的缓存比较稳妥

posted @ 2018-01-26 17:29  在谷歌上百度  阅读(277)  评论(0编辑  收藏  举报