Mybatis缓存详解

Mybatis缓存

执行流程

img

[外链图片转存中...(img-CFjetrZr-1596032247712)]

进行数据库查询,首先查看二级缓存有没有数据,通过MappedStatment和传入的对象,进行Hash,获取数据。有数据就取数据,没有就从数据库取数据,并放入缓存中。

缓存类别

一级缓存

  1. SqlSession

  2. Statemen

    Mybatis的一级缓存是关闭不掉的,默认开启的,也正是因为关闭掉,所以才存在了Statement的级别,粒度再次调小,不再是SqlSession,而是Statement级别。每次执行语句,都会清除缓存。

二级缓存配置 (CacheExcutor内部维护)

@CacheNamespace(
        implementation = MyConfig.class,    //缓存实现类,内部维护一个HashMap(或其他),将命名空间作为键,存放下面的HashMap
        eviction = FifoCache.class,     
    //MappedStatement和传入对象加盐hash,查询结果为value存入,最后存入Myconfig维护的HashMap中
    //四中取值 FifoCache   LruCache   WeakCache  SoftCache
        flushInterval=150000,
    //维护的HashMap最大值
        size = 1024,
    //维护数据可不可以更改
    	readWrite=bool,
    // 读缓存堵塞不堵塞
    blocking=bool
)
eviction
LRU:移除最长时间不被使用的对象,这是默认值。
FIFO:按对象进入缓存的顺序来移除它们。
SOFT:移除基于垃圾回收器状态和软引用规则的对象。
WEAK:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushinterval
可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况不设置,即没有刷新间隔,缓存仅仅在调用语句时刷新。
size
可以被设置为任意正整数,要记住缓存的对象数目和运行环境的可用内存资源数目。默认值是1024 。
readOnly
属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,这提供了很重要的性能优势。

可读写的缓存会通过序列化返回缓存对象的拷贝,这种方式会慢一些,但是安全,因此默认是 false。

三级缓存(自定义缓存)

注解配置
@CacheNamespace(
        implementation = MyConfig.class,实现Cache接口即可
        eviction = FifoCache.class,
        flushInterval=150000,
        size = 1024
)

注解配置

@CacheNamespace

配置缓存储存的方案

@CacheNamespaceRef

与xml配置文件共同使用

@Options

useCache=true, flushCache

代替xml配置中的useFlush 方法执行前刷新内存,不用在手动刷新缓存

缓存清除

  1. flushStatement

    每次执行sql语句都会清除Excutor中的缓存数据

  2. clearCache

    清除Excutor中维护的persistentCache维护的hashMap

  3. commit

    commit清除,实质内部调用flushstatemen和clearCache

  4. close

    sqlSession关闭,会自己清除sqlSession中的换粗

代码测试

public class App {
    public static void main(String[] args) throws IOException, InterruptedException {
        InputStream is = Resources.getResourceAsStream("MybatisConfig.xml");
        SqlSessionFactory fac = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = fac.openSession();
        // 一级缓存SqlSession使用
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk);
//        Book bk1 = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk1);

        // StateMent级别     修改配置
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk);
//        Book bk1 = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk1);


        //SqlSession缓存清除
        //1
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk);
////        sqlSession.clearCache();
//        Book bk1 = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk1);

        //2
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk);
//        sqlSession.update("updtRose");
//        Book bk1 = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk1);

        //3
        //sqlSession关闭缓存清除
        //4
        //commit()

        //二级缓存  都为true   开配置2!!   domain???
        // 1 Commit异常         CachingExecutor
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        System.out.println(bk);
////        sqlSession.commit();
//        SqlSession sqlSession1=fac.openSession(true);
//        Book bk1 = (Book) sqlSession1.selectOne("findOne");
//        System.out.println(bk1);

        //缓存清除
        //一样省略


        //2.5?扩展 funny
        //注意事务开启 ? 手动数据修改 与 commit提交参数  BaseExcutor
        // commit 请求清除
//        commit与commit(boolean)

        //三级缓存
//        Book bk = (Book) sqlSession.selectOne("findOne");
//        sqlSession.commit();
//        Set<Object> objs = MyConfig.myCache.keySet();
//        System.out.println(objs.toArray()[0].toString());   //可以看到HashMap的Cache值
 
        
        //Dao层
        //@CacheNamespace(
//        eviction = FifoCache.class,
//        flushInterval=150000,
//        size = 1024
//
//)
//@CacheNamespace(
//        implementation = MyConfig.class,
//        eviction = FifoCache.class,
//        flushInterval=150000,
//        size = 1024
//)
public interface DaoBook {
    @Select("select * from book limit 1")
    Book findOne();
//    @Options(
//            useCache = false
//    )
    @Update("update book set author=\"Rose\" where BID=\"B001\"")
    Book updtRose();
}
        
        //实体
        public class Book{
    private String BID;
    private String title;
    private String author;

    public String getBID() {
        return BID;
    }

    public void setBID(String BID) {
        this.BID = BID;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "DaoBook{" +
                "BID='" + BID + '\'' +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

转载于https://www.cnblogs.com/wuzhenzhao/p/11103043.html

posted @ 2021-01-27 19:51  站在巨人肩上的人  阅读(368)  评论(0编辑  收藏  举报