资讯专栏INFORMATION COLUMN

MyBatis 缓存

Edison / 2152人阅读

摘要:一级缓存对于一级缓存来说是直接单个线程隔离的在执行的时候会自动清空缓存避免脏读造成的影响此时为线程隔离的而管理对象为所有线程所共享的修改展示层获取开始时间获取结束时间查看日志可以看到只查

一级缓存

对于一级缓存来说,Mybatis是直接单个线程隔离的
在执行add,update,delete 的时候,会自动清空缓存,避免脏读造成的影响
此时mapper为线程隔离的,而管理对象为所有线程所共享的.

修改展示层

<%@ page import="org.apache.ibatis.session.SqlSession" %>
<%@ page import="com.ming.Util.SqlSessionFactoryUtil" %>
<%@ page import="com.ming.MyBatis.RoleMapper" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="com.ming.MyBatis.POJO.Student" %>


Hello World!

<% long startTime = System.currentTimeMillis(); //获取开始时间 SqlSession sqlSession = null; List students = null; List students1 = null; try { sqlSession = SqlSessionFactoryUtil.openSqlSesion(); RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class); students = roleMapper.getStudent(1); students1 = roleMapper.getStudent(1); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); } finally { if (sqlSession != null) { sqlSession.close(); } } long endTime = System.currentTimeMillis(); //获取结束时间 %> <% Iterator iterator = students.iterator(); while(iterator.hasNext()){ %> <%=((Student)iterator.next()).getGender()%> <% } iterator = students1.iterator(); while(iterator.hasNext()){ %> <%=((Student)iterator.next()).getGender()%> <% } %>

查看日志

2019-04-17 22:33:38.147 [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:136) - Opening JDBC Connection
2019-04-17 22:33:38.147 [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:397) - Checked out connection 879027360 from pool.
2019-04-17 22:33:38.148 [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction.setDesiredAutoCommit(JdbcTransaction.java:100) - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3464e4a0]
2019-04-17 22:33:38.161 [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143) - ==>  Preparing: SELECT student.uid, student.gender, student.remarks, student.student_id_number, student.student_name FROM student WHERE student.uid = 1; 
2019-04-17 22:33:38.162 [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143) - ==> Parameters: 
2019-04-17 22:33:38.181 [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:143) - <==      Total: 1
2019-04-17 22:33:38.183 [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction.resetAutoCommit(JdbcTransaction.java:122) - Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3464e4a0]
2019-04-17 22:33:38.200 [DEBUG] org.apache.ibatis.transaction.jdbc.JdbcTransaction.close(JdbcTransaction.java:90) - Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3464e4a0]
2019-04-17 22:33:38.201 [DEBUG] org.apache.ibatis.datasource.pooled.PooledDataSource.pushConnection(PooledDataSource.java:362) - Returned connection 879027360 to pool.

可以看到只查询了一次

需要注意的是缓存在各个SqlSession是相互隔离的

二级缓存

二级缓存直接添加cache即可





    
    
        
        
        
        
        
        
    
    
    
    
    
    
    
    
    
    
        
        
        
        
        
        
    

    
    
    
        
        
        
        
        
        
        
    
    
    
    
    

此时select语句将会缓存
insert update delete 将会刷新缓存
会使用LRU算法进行回收
根据时间表 缓存不会用任何时间顺序来刷新缓存
缓存会存储列表集合或对象 1024个引用

由于对象需要序列化所以需要实现 java.io.Serializable接口

父类实现序列化 子类会自动实现序列化 若子类实现序列化 父类没有实现序列化 此时在子类中保存父类的值,直接跳过
2019-04-18 00:55:44.428 [DEBUG] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62) - Cache Hit Ratio [com.ming.MyBatis.RoleMapper]: 0.7586206896551724
2019-04-18 00:55:44.430 [DEBUG] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62) - Cache Hit Ratio [com.ming.MyBatis.RoleMapper]: 0.7666666666666667
2019-04-18 00:55:44.433 [DEBUG] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62) - Cache Hit Ratio [com.ming.MyBatis.RoleMapper]: 0.7741935483870968
2019-04-18 00:55:44.435 [DEBUG] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62) - Cache Hit Ratio [com.ming.MyBatis.RoleMapper]: 0.78125

查看日志,可以发现再次读取的时候,直接从缓存中获取了.
缓存生效,并为执行sql语句

已经命中缓存

自定义缓存

这个需要实现cache接口

package com.ming.MyBatis;

import java.util.concurrent.locks.ReadWriteLock;

/**
 * @author ming
 */
public class Cache implements org.apache.ibatis.cache.Cache {
    /**
     * @return The identifier of this cache
     */
    @Override
    public String getId() {
        return null;
    }

    /**
     * @param key   Can be any object but usually it is a {@link CacheKey}
     * @param value The result of a select.
     */
    @Override
    public void putObject(Object key, Object value) {

    }

    /**
     * @param key The key
     * @return The object stored in the cache.
     */
    @Override
    public Object getObject(Object key) {
        return null;
    }

    /**
     * As of 3.3.0 this method is only called during a rollback
     * for any previous value that was missing in the cache.
     * This lets any blocking cache to release the lock that
     * may have previously put on the key.
     * A blocking cache puts a lock when a value is null
     * and releases it when the value is back again.
     * This way other threads will wait for the value to be
     * available instead of hitting the database.
     *
     * @param key The key
     * @return Not used
     */
    @Override
    public Object removeObject(Object key) {
        return null;
    }

    /**
     * Clears this cache instance.
     */
    @Override
    public void clear() {

    }

    /**
     * Optional. This method is not called by the core.
     *
     * @return The number of elements stored in the cache (not its capacity).
     */
    @Override
    public int getSize() {
        return 0;
    }

    /**
     * Optional. As of 3.2.6 this method is no longer called by the core.
     * 

* Any locking needed by the cache must be provided internally by the cache provider. * * @return A ReadWriteLock */ @Override public ReadWriteLock getReadWriteLock() { return null; } }

然后redis直接操作即可

额...暂时先不连接

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74190.html

相关文章

  • Mybatis【逆向工程,缓存,代理】知识要点

    摘要:一级缓存值得注意的地方默认就是支持一级缓存的,并不需要我们配置和整合后进行代理开发,不支持一级缓存,和整合,按照的模板去生成代理对象,模板中在最后统一关闭。总结的一级缓存是级别的。 前言 本文主要讲解Mybatis的以下知识点: Mybatis缓存 一级缓存 二级缓存 与Ehcache整合 Mapper代理 使用Mapper代理就不用写实现类了 逆向工程 自动生成代码 ...

    wanglu1209 评论0 收藏0
  • MyBatis知识点整理

    摘要:得到用户信息,将用户信息存储到一级缓存中。如果中间去执行操作执行插入更新删除,则会清空中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。 基础: 1、 概念:Java当中的一个持久层框架。2、 特点、优势:(1)把java代码和SQL代码做了一个完全分离。(2)良好支持复杂对象的映射(输入映射、输出映射)(3)使用动态SQL,可以预防SQL注入。3、 ...

    zhangqh 评论0 收藏0
  • MyBatis缓存介绍

    摘要:缓存介绍正如大多数持久层框架一样,同样提供了一级缓存和二级缓存的支持一级缓存基于的本地缓存,其存储作用域为,当或之后,该中的所有就将清空。一级缓存实现对的操作内部都是通过来执行的。 MyBatis缓存介绍   正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持   一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se...

    mingde 评论0 收藏0
  • Spring Boot2(二):使用Spring Boot2集成Mybatis缓存机制

    摘要:本文章的源码再文章末尾什么是查询缓存有一级缓存和二级缓存。默认开启一级缓存。证明了一级缓存只是在数据库会话内部共享的。但是,整合到中后,一级缓存就会被关闭。根据时间表比如没有刷新间隔缓存不会以任何时间顺序来刷新。 仓库地址:spring-boot-learning欢迎star、fork,给作者一些鼓励 学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机...

    mikasa 评论0 收藏0
  • Spring Boot2(二):使用Spring Boot2集成Mybatis缓存机制

    摘要:本文章的源码再文章末尾什么是查询缓存有一级缓存和二级缓存。默认开启一级缓存。证明了一级缓存只是在数据库会话内部共享的。但是,整合到中后,一级缓存就会被关闭。根据时间表比如没有刷新间隔缓存不会以任何时间顺序来刷新。 仓库地址:spring-boot-learning欢迎star、fork,给作者一些鼓励 学习SpringBoot集成Mybatis的第二章,了解到Mybatis自带的缓存机...

    NSFish 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<