MyBatis 缓存
一级缓存
对于一级缓存来说,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" %> <html> <body> <h2>Hello World!</h2> <% long startTime = System.currentTimeMillis(); //获取开始时间 SqlSession sqlSession = null; List<Student> students = null; List<Student> 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()%> <% } %> </body> </html>
查看日志
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即可
<?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.ming.MyBatis.RoleMapper"> <resultMap type="role" id="roleMap"> <!-- id为主键映射关系 其中数据库中的id为主键 --> <id column="id" property="id" javaType="int" jdbcType="INTEGER"/> <!-- result为其他基本数据类型和实体类之间的映射 映射关系为role_name 到 roleName之间的映射 数据类型为string到VARCHAR之间的映射关系 --> <result column="role_name" property="roleName" javaType="string" jdbcType="VARCHAR"/> <!-- 这里使用typeHandler表示遇到此处理集的时候,将会执行com.ming.MyBatis.StringTypeHandler --> <result column="note" property="note" typeHandler="com.ming.MyBatis.StringTypeHandler"/> </resultMap> <select id="getRole" parameterType="int" resultType="com.ming.MyBatis.POJO.Role"> SELECT id, role_name as roleName, note FROM t_role WHERE id = #{id} </select> <select id="findRoleByteMap" parameterType="map" resultMap="roleMap"> SELECT id, role_name, note FROM t_role WHERE role_name LIKE CONCAT('%', #{roleName}, '%') AND note LIKE CONCAT('%', #{note}, '%') </select> <select id="findRoleByteMap1" resultMap="roleMap"> SELECT id, role_name, note FROM t_role WHERE role_name LIKE CONCAT('%', #{roleName}, '%') AND note LIKE CONCAT('%', #{note}, '%') </select> <resultMap id="studentSelfCardMap" type="com.ming.MyBatis.POJO.StudentCard"> <id column="uid" property="uid"/> <result column="student_number" property="studentNumber"/> <result column="birthplace" property="birthplace" /> <result column="date_of_issue" property="dateOfIssue" jdbcType="DATE" javaType="java.util.Date"/> <result column="end_date" property="endDate" jdbcType="DATE" javaType="java.util.Date"/> <result column="remarks" property="remarks" /> </resultMap> <select id="findStudentSelfCardByStudentId" parameterType="int" resultMap="studentSelfCardMap"> SELECT student_card.uid, student_card.student_number, student_card.remarks, student_card.end_date, student_card.date_of_issue, student_card.birthplace FROM student_card WHERE student_card.uid = #{studentId}; </select> <resultMap id="studentMap" type="com.ming.MyBatis.POJO.Student"> <id column="uid" property="uid"/> <result column="student_name" property="studentName"/> <result column="gender" property="gender"/> <result column="student_id_number" property="studentIdNumber"/> <result column="remarks" property="remarks"/> <!--将会调用接口代表的SQL 进行执行查询 --> <association property="studentCard" column="uid" select="com.ming.MyBatis.RoleMapper.findStudentSelfCardByStudentId"/> </resultMap> <select id="getStudent" parameterType="int" resultMap="studentMap"> SELECT student.uid, student.gender, student.remarks, student.student_id_number, student.student_name FROM student WHERE student.uid = 1; </select> <cache/> </mapper>
此时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. * <p> * Any locking needed by the cache must be provided internally by the cache provider. * * @return A ReadWriteLock */ @Override public ReadWriteLock getReadWriteLock() { return null; } }
然后redis直接操作即可
额...暂时先不连接
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
【云周刊】第215期:阿里靠什么支撑 EB 级计算力?
欢迎订阅云周刊 本期头条 阿里靠什么支撑 EB 级计算力? MaxCompute 是阿里EB级计算平台,经过十年磨砺,它成为阿里巴巴集团数据中台的计算核心和阿里云大数据的基础服务。去年MaxCompute 做了哪些工作,这些工作背后的原因是什么?大数据市场进入普惠+红海的新阶段,如何与生态发展共赢?人工智能进入井喷阶段,如何支持与借力?本文从过去一年的总结,核心技术概览,以及每条技术线路未来展望等几个方面做一个概述。点击查看 Tablestore Timestream:为海量时序数据存储设计的全新数据模型阿里巴巴小程序繁星计划ELK日志分析方案【云吞铺子】性能抖动剖析(一)香港特首参观杭州城市大脑,阿里云技术获赞蚂蚁金服高级研究员阳振坤:为什么我们要选择自研数据库这条艰难之路蠕虫利用新公开的Confluence RCE漏洞进行大规模攻击,
- 下一篇
老生常谈 String、StringBuilder、StringBuffer
[TOC] 字符串就是一连串的字符序列,Java提供了String、StringBuilder、StringBuffer三个类来封装字符串 String String类是不可变类,String对象被创建以后,对象中的字符序列是不可改变的,直到这个对象被销毁 为什么是不可变的 jdk1.8 public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; //jdk1.9中将char数组替换为byte数组,紧凑字符串带来的优势:更小的内存占用,更快的操作速度。 //构造函数 public String(String original) { this.value = original.value; this.hash = original.hash; } //构造函数 public String(char v...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 2048小游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS8编译安装MySQL8.0.19
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题