• 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直接操作即可

    额...暂时先不连接

    在无知的道路上缓步前行
  • 相关阅读:
    手机号中间几位用****代替
    正则小数点保留后两位;只允许汉字字母1-20位;10位数纯数字;正整数
    正则1-30之间的数值,支持1位小数
    给ul => li 中的最后一个li不加伪类after; 或者给最后一个和第一个不加伪类
    ajax请求, 前后端, 代码示例
    最简单的操作 jetty IDEA 【debug】热加载
    maven win 安装 与 IntelliJ IDEA 配置Maven【2018-11-14最新最有姿势攻略】
    mysql 在 win 安装 最全攻略(附转载的乱码终极解决方案)以及解决data too long for column 'name' at row 1, 一种可能就是因为编码一致性问题.
    SpringBoot无法书写主启动类的情况之一
    扯淡设计模式2:java,模板模式,
  • 原文地址:https://www.cnblogs.com/melovemingming/p/10738480.html
Copyright © 2020-2023  润新知