mybats redis二级缓存扩展

Mybatis扩展篇 Mybatis功能扩展篇 阅读详情

mybatis实现自定义二级缓存,最简单的做法,实现一个org.apache.ibatis.cache.Cache接口就可以了

然后就是在sql xml文件里使用,<cache eviction="LRU" type="com.mark.demo.shiro.mybatis.cache.MyBatisRedisCache" ></cache>

这种简单实现有更新操作时会过期同一个配置文件里的查询缓存,但是跨配置文件就不好处理了。

为了处理跨配置文件更新过期,需要自己实现RedisCachingExecutor implements Interceptor 

下面贴代码:

package com.mark.demo.shiro.mybatis.cache;

import java.io.Serializable;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.cache.CacheKey;

import com.mark.demo.shiro.utils.JedisUtils;
import com.mark.demo.shiro.utils.ObjectUtils;

/*
*hxp(hxpwangyi@126.com)
*2017年9月8日
*
*/
public class MyBatisRedisCache implements Cache,Serializable{
	public static final String mybatis_cache_prefix="mybatis_cache";

	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

	private String id;

	public MyBatisRedisCache(final String id) {
	    if (id == null) {
	        throw new IllegalArgumentException("缓存没有初始化id");
	    }
	    this.id = id;
	}

	@Override
	public String getId() {
	    return this.id;
	}

	@Override
	public int getSize() {
		
	    return JedisUtils.getMapLen(mybatis_cache_prefix);
	}

	@Override
	public void putObject(Object key, Object value) {
		CacheKey cacheKey=(CacheKey)key;
		String [] keyAry=cacheKey.toString().split(":");
		String myKey=keyAry[2];
	    JedisUtils.setMapField(mybatis_cache_prefix, ObjectUtils.serialize(myKey), value);
	}
	@Override
	public Object getObject(Object key) {
		CacheKey cacheKey=(CacheKey)key;
		String [] keyAry=cacheKey.toString().split(":");
		String myKey=keyAry[2];
	    return JedisUtils.getMapFiled(mybatis_cache_prefix, ObjectUtils.serialize(myKey));
	    
	}

	@Override
	public Object removeObject(Object key) {
	    Object ret=JedisUtils.getMapFiled(mybatis_cache_prefix, ObjectUtils.serialize(key));
		JedisUtils.removeMapField(mybatis_cache_prefix, ObjectUtils.serialize(key));
		return ret;
	}

	@Override
	public void clear() {
	    JedisUtils.del(mybatis_cache_prefix);
	}

	@Override
	public ReadWriteLock getReadWriteLock() {
	    return readWriteLock;
	}

}
package com.mark.demo.shiro.mybatis.cache;

import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

/*
*hxp(hxpwangyi@126.com)
*2017年9月8日
*
*/
@Intercepts(value = {
		@Signature(args = {MappedStatement.class, Object.class, RowBounds.class,ResultHandler.class}, method = "query", type = Executor.class),
		@Signature(args = {MappedStatement.class, Object.class}, method = "update", type = Executor.class),
		@Signature(args = {boolean.class}, method = "commit", type = Executor.class),
		@Signature(args = {boolean.class}, method = "rollback", type = Executor.class),
		@Signature(args = {boolean.class}, method = "close", type = Executor.class)
})
public  class RedisCachingExecutor implements Interceptor {
	private Set<String>   updateStatementOnCommit = new HashSet<String>();
	RedisCachingManager cachingManager = RedisCachingManagerImpl.getInstance();
	
	public Object intercept(Invocation invocation) throws Throwable {
		String name = invocation.getMethod().getName();
		Object result =null;
		if("query".equals(name))
		{
			result = this.processQuery(invocation);
		}
		else if("update".equals(name))
		{
			result = this.processUpdate(invocation);
		}
		else if("commit".equals(name))
		{
			result = this.processCommit(invocation);
		}
		else if("rollback".equals(name))
		{
			result = this.processRollback(invocation);
		}
		else if("close".equals(name))
		{
			result = this.processClose(invocation);
		}
		return result;
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	/**
	 * when executing a query operation
	 * 1. record this statement's id and it's corresponding Cache Object into Global Caching Manager;
	 * 2. record this statement's id and  
	 * @param invocation
	 * @return
	 * @throws Throwable
	 */
	protected Object processQuery(Invocation invocation) throws Throwable {
		Object result = invocation.proceed();
		return result;
	}
	
	protected Object processUpdate(Invocation invocation) throws Throwable {
	
		Object result = invocation.proceed();
		MappedStatement mappedStatement = (MappedStatement)invocation.getArgs()[0];
		updateStatementOnCommit.add(mappedStatement.getId());
		return result;
	}

	protected Object processCommit(Invocation invocation) throws Throwable {
		Object result  = invocation.proceed();
		refreshCache();
		return result;
	}

	protected Object processRollback(Invocation invocation) throws Throwable {
	    Object result = invocation.proceed();
	    clearSessionData();
		return result;
	}

	protected Object processClose(Invocation invocation) throws Throwable {
		Object result = invocation.proceed();
		boolean forceRollback = (Boolean) invocation.getArgs()[0];
		if(forceRollback)
		{
			clearSessionData();
		}
		else
		{
			refreshCache();
		}
		return result;
	}
	
	
	
	/**
	 * when the sqlSession has been committed,rollbacked,or closed,
	 * session buffer query CacheKeys and update Statement collections should be cleared.
	 * 
	 * 当SqlSession 执行了commit()、rollback()、close()方法,
	 * Session级别的查询语句产生的CacheKey集合以及  执行的更新语句集合应该被清空
	 */
	private synchronized void clearSessionData()
	{
	    updateStatementOnCommit.clear();
	}
	
	
	
	/**
	 * refresh the session cache,there are two things have to do:
	 * 1. add this session scope query logs to global cache Manager 
	 * 2. clear the related caches according to the update statements as configured in "dependency" file
	 * 3. clear the session data
	 */
	private synchronized void refreshCache()
	{
		cachingManager.clearRelatedCaches(updateStatementOnCommit);
		clearSessionData();
	}
	
	/**
	 * 
	 * 
	 * Executor插件配置信息加载点
	 * properties中有 "dependency" 属性来指示 配置的缓存依赖配置信息,读取文件,初始化EnhancedCacheManager
	 */
	public void setProperties(Properties properties) {
		
		if(!cachingManager.isInitialized())
		{
			cachingManager.initialize(properties);
		}
	}
}

package com.mark.demo.shiro.mybatis.cache;

import java.util.Properties;
import java.util.Set;

import org.apache.ibatis.cache.Cache;



public interface RedisCachingManager {
	
	
	public boolean isInitialized();
	
	/**
	 * MyBatis是否开启了二级缓存,即 <setting name="cacheEnabled" value="true"/> 
	 * @return
	 */
	public boolean isCacheEnabled();

	/**
	 * 
	 * 初始化 缓存管理器,应该只被调用一次;
	 * 
	 * @param properties
	 * 	properties 中至少包含两个属性:
	 * 		dependency 	: 该值表示着缓存依赖配置文件的位置
	 * 		cacheEnbled	: "true" or "false",该配置必须要与<setting name="cacheEnabled">的值保持一致
	 */
	public void initialize(Properties properties);
	
	
	/**
	 * 整个插件的核心,根据指定的statementId更新与之关联的二级缓存
	 * 传入的StatementId集合是由会话级别的update语句对应的StatementId,
	 * EnhancedCachingManager将通过查询相应的StatementId去查看是否配置了依赖关系,如果有,则将依赖关系中的statementId的查询缓存全部清空
	 * @param set
	 */
	public void clearRelatedCaches(Set<String> set);
	
	

}

package com.mark.demo.shiro.mybatis.cache;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;

import com.mark.demo.shiro.utils.JedisUtils;
import com.mark.demo.shiro.utils.PropertiesLoader;

public class RedisCachingManagerImpl implements RedisCachingManager{
	
	//每一个statementId 更新依赖的statementId集合
	private Map<String,Set<String>> observers=new ConcurrentHashMap<String,Set<String>>();
	
	private boolean initialized = false;
	private boolean cacheEnabled = false;
	
	private volatile static RedisCachingManagerImpl enhancedCacheManager;

	private RedisCachingManagerImpl(){}
	public static RedisCachingManagerImpl getInstance()
	{
		if(enhancedCacheManager==null){
			synchronized (RedisCachingManagerImpl.class) {
				if(enhancedCacheManager==null){
					enhancedCacheManager=new RedisCachingManagerImpl();
				}
			}
		}
		return enhancedCacheManager;
	}
	
	public void clearRelatedCaches(final Set<String> set) {
		for(String observable:set)
		{
			Set<String> relatedStatements = observers.get(observable);
			for(String statementId:relatedStatements)
			{
				JedisUtils.removeMapField(MyBatisRedisCache.mybatis_cache_prefix, statementId);
			}
		}
	}
	public boolean isInitialized() {
		return initialized;
	}
	
	public void initialize(Properties properties)
	{
		PropertiesLoader loader=new PropertiesLoader("mybatis.properties");
		String dependency = loader.getProperty("dependencys");
		if(!("".equals(dependency) || dependency==null))
		{
			InputStream inputStream;
			try 
			{
					inputStream = Resources.getResourceAsStream(dependency);
					XPathParser parser = new XPathParser(inputStream);
					List<XNode> statements = parser.evalNodes("/dependencies/statements/statement");
					for(XNode node :statements)
					{
						Set<String> temp = new HashSet<String>();
						List<XNode> obs = node.evalNodes("observer");
						for(XNode observer:obs)
						{
							temp.add(observer.getStringAttribute("id"));
						}
						this.observers.put(node.getStringAttribute("id"), temp);
					}
					initialized = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		//cacheEnabled
		String cacheEnabled = properties.getProperty("cacheEnabled", "true");
		if("true".equals(cacheEnabled))
		{
			this.cacheEnabled = true;
		}
	}
	
	public boolean isCacheEnabled() {
		return cacheEnabled;
	}
}


<?xml version="1.0" encoding="UTF-8"?>
<dependencies>
    <statements>
        <!-- 角色授权后刷新角色缓存 -->
        <statement id="com.mark.demo.shiro.mapper.MenuMapper.updateMenu">
        	<observer id="com.mark.demo.shiro.mapper.UserMapper.getMenuTopLever"/>
        </statement>

    </statements>
</dependencies>


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 全局参数 -->
    <settings>
        <!-- 使全局的映射器启用或禁用缓存。 -->
        <setting name="cacheEnabled" value="true"/>

        <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
        <setting name="lazyLoadingEnabled" value="false"/>

        <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
        <setting name="aggressiveLazyLoading" value="true"/>

        <!-- 是否允许单条sql 返回多个数据集  (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>

        <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>

        <!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false  -->
        <setting name="useGeneratedKeys" value="false"/>

        <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分  FULL:全部  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        <!-- 这是默认的执行类型  (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新)  -->
        <setting name="defaultExecutorType" value="REUSE"/>

        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!-- 设置本地缓存范围 session:就会有数据的共享  statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
        <setting name="localCacheScope" value="STATEMENT"/>

        <!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>

    </settings>
	
	<typeAliases>
	     <package name="com.mark.demo.shiro.entity" />
	</typeAliases>
	
    <!-- 插件配置 -->
    <plugins>
        <plugin interceptor="com.mark.demo.shiro.mybatis.PaginationInterceptor"/>
        <plugin interceptor="com.mark.demo.shiro.mybatis.cache.RedisCachingExecutor">
            <property name="dependency" value="dependencys.xml"/>
            <property name="cacheEnabled" value="true"/>
        </plugin>
    </plugins>

</configuration>
<?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.mark.demo.shiro.mapper.UserMapper">
	<cache eviction="LRU" type="com.mark.demo.shiro.mybatis.cache.MyBatisRedisCache" ></cache>
    <resultMap type="User" id="userMap">
    	<result column="userId" property="id" />
    	<result column="userName" property="userName" />
    	<result column="password" property="password" />
    	<result column="age" property="age" />
    	<result column="sex" property="sex" />
    	<result column="phone" property="phone" />
    </resultMap>
    
    <select id="getUserByUserName" parameterType="String" resultMap="userMap">
    	select * from user where userName=#{userName}
    </select>
    
    <resultMap type="Menu" id="menuMap">
    	<result column="menuId" property="id"/>
    	<result column="menuName" property="menuName"/>
    	<result column="menuDesc" property="menuDesc"/>
    	<result column="link" property="link"/>
    	<result column="icon" property="icon"/>
    </resultMap>
    
    <select id="getMenuTopLever"  resultMap="menuMap" useCache="true">
    	select * from menu where pid=-1
    </select>
</mapper>


demo地址:https://github.com/13567436138/shiro-demo.git

windows在使用ping 127.0.0.1时出现一般故障的解决方案 本文主要介绍了windows在使用ping 127.0.0.1时出现一般故障的解决方案,希望能对使用windows的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案 阅读详情

相关推荐

从“看不懂Sansen”到亲手搭建:一个Class AB输出级+浮动电压源的保姆级设计复盘

本文详细记录了从理论困惑到实践突破的Class AB输出级与浮动电压源设计全过程。通过电流镜调试、恒定跨导优化及版图匹配等关键步骤,作者实现了高性能运放设计,并分享了从仿真到实测的宝贵经验,为模拟电路初学者提供实用指导。

weixin_33737774的博客 869

MyBatis缓存详解

缓存是一般ORM框架都会提供的功能, 目的就是提升查询的效率和减少数据库的压力。和Hibernate一样,MyBatis也提供一级缓存和二级缓存的功能,并预留了集成第三方缓存的接口。 MyBatis跟缓存相关的类都在cache包里面,其中有一个Cache接口,且只有一个实现类PerpetualCache,它是用HashMap实现缓存功能的。 除此之外,还有很多的装饰器,通过这些装饰器可以实现很多额...

yang的博客 3388

RK3568下YT8531/YT8521 PHY移植避坑指南:RGMII与设备树详解

嵌入式Linux网络调试中,PHY芯片作为MAC与物理介质之间的桥梁,其驱动配置直接影响网络稳定性。RGMII接口的延时补偿、PHY地址设定以及复位时序是设备树配置中的关键环节,稍有差错便会出现链路已通却无法通信的现象。通过理解PHYLIB框架与mdio总线枚举原理,开发者可以快速定位寄存器级故障。在RK3568等工业级平台中,裕太微YT8531/YT8521凭借高性价比与内核主线支持,成为替代传统方案的热门选择。从设备树模板、内核配置到常见坑点,系统梳理千兆以太网PHY的移植与调试方法,帮助开发者少走弯路

weixin_29189381的博客 215

手撕 MyBatis 可插拔式缓存设计(拓展)

手撕 MyBatis 可插拔式缓存设计

weixin_48206782的博客 361

【强化学习】常用算法之一 “A3C”

A3C(Asynchronous Advantage Actor-Critic)算法是一种在强化学习领域中应用广泛的算法,它结合了策略梯度方法和价值函数的学习,用于近似解决马尔可夫决策过程(Markov Decision Process)问题。A3C算法在近年来备受关注,因为它在处理大规模连续动作空间和高维状态空间方面具有出色的性能。A3C算法是一种基于策略梯度的强化学习算法,通过多个并行的智能体异步地与环境交互,并利用Actor和Critic网络实现策略和价值的近似,从而实现快速而稳定的强化学习训练。

Code_and516的博客 6759

配电网故障重构/孤岛划分/故障恢复

程序主要复现《基于GA_BFGS算法的配电网故障恢复性重构研究_郑海广》,采用matlab编程软件实现,依据网络结构和DG供电方式对配电网进行孤岛划分,将含有 DG 的配电网拓扑结构看成一个树,搭建成连通图模型,使得将孤岛的划分变成了求取最小生成树,以网损和开关开断次数作为目标,采用 IEEE33 节点配电网为算例,通过遗传算法寻优计算,从而得到最佳的重构方案。

zhangxd212489的博客 2501

如何细粒度地控制你的MyBatis二级缓存(mybatis-enhanced-cache插件实现)

本文如下组织结构: 一个关于MyBatis的二级缓存的实际问题 当前MyBatis二级缓存的工作机制 mybatis-enhanced-cache插件的设计和工作原理 mybatis-enhanced-cache 插件的使用实例 1.一个关于MyBatis的二级缓存的实际问题 现有AMapper.xml中定义了对数据库表 ATable 的CRUD操作,BMapper定义了对数据库表...

laomumu1992的博客 269

图像调整亮度饱和度 c语言,【C#/WPF】调节图像的HSL(色相、饱和度、明亮度)...

先说概念:HSL是一种描述颜色的方式(其他颜色描述方式还有大家熟悉的RGB值)。HSL三个字母分别表示图像的Hue色相、Saturation饱和度、Lightness明亮度。需求:制作一个面板,包含三个滑动条,拖动滑动条可以修改目标图片的HSL值。即模仿PS中类似的功能,如下图:方案一:遍历所有像素点,修改每个点的HSL值。前台界面:一个Image控件显示目标图片,一个Button按钮点击一下降低...

weixin_39935777的博客 1157

mybatis 源码刨析扩展之 二级缓存

目录一、复习一下二级缓存内容1、启动二级缓存1)开启全局二级缓存配置2)在需要使用二级缓存的 Mapper 配置文件中配置标签3)在具体 CURD 标签上配置 useCache=true二、源码刨析1、配置初始化,标签 的解析1)XMLConfigBuilder2)我们来看看解析 Mapper.xml3)看看是如何构建 Cache 对象的4)buildStatementFromContext(context.evalNodes("select|insert|update|delete")); 将 Cach

jason559的博客 437

UG\NX二次开发 使用UF_CURVE_create_ocf_feature函数创建“在面上偏置”特征

使用UF_CURVE_create_ocf_feature函数创建“在面上偏置”特征。

王牌飞行员_里海的博客 850

姿态传感器/陀螺仪之ICM-42670-P应用原理图设计

ICM-42670-P采用LGA-14封装,尺寸为2.5x3x0.76毫米,工作电压范围为1.71V至3.6V,支持I3CSM、I2C和SPI串行通信接口。其设计目标是提供高精度、低功耗和小型化的解决方案,以满足消费类和工业应用的需求。ICM-42670-P是一款由TDK InvenSense推出的高性能六轴MEMS运动追踪传感器,集成了3轴陀螺仪和3轴加速度计,适用于多种应用场景,包括可穿戴设备、游戏控制器、无人机、AR/VR设备等。

corlin6688的博客 1207

理解Mybatis的缓存机制

理解Mybatis的缓存机制 最近在解决性能问题的时候,在与spring btach中的某个tasklet分页查询数据并进行数据的处理的时候,大概压了40w的数据,当然在结果集中解析出来的数据对象更大,结果导致了OOM问题,用内存分析工具MemoryAnalyzer查看到了大对象的内存占用指向了mybatis查询出来的对象,然后就去跟踪调用,结果跟踪到了mybatis的CacheExecutor,于是想到可能是mybatis的缓存,但是之前没有对它进行详细的了解,所以就掉坑里了,没有仔细的思考,很轻易的跳过

loveuserzzz的专栏 582

7、农业市场价格预测与K-Means聚类算法的综合研究

本文综合研究了农业市场价格预测与K-Means聚类算法的原理、应用及拓展。在农业领域,基于历史数据和供应信息的价格预测模型可为农民、政府和金融机构提供决策支持;在数据处理领域,K-Means算法通过合理选择初始质心和距离度量方法,实现高效聚类分析。文章还探讨了两种技术面临的挑战与解决方案,并展望了其在大数据、人工智能融合背景下的未来发展趋势,展示了跨领域技术协同的应用潜力。

ujm56789012的博客 67

SSM框架实现企业员工管理系统的关键技术与实践

企业管理系统是现代企业数字化转型的核心组件,基于SSM(Spring+SpringMVC+MyBatis)框架的开发模式因其成熟稳定、易于扩展的特点成为Java开发的首选方案。SSM框架通过依赖注入和AOP编程实现松耦合架构,MyBatis的ORM映射简化数据库操作,结合Maven进行高效的依赖管理。在人力资源管理场景中,这类系统需要重点解决权限控制、数据加密、报表生成等技术难点,其中使用Apache POI处理Excel导入导出、采用BCrypt加密存储敏感信息是典型实现方案。本文以员工考勤系统为例,详解

weixin_33849215的博客 373

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MyBatis中如何实现缓存的扩展

2.考察你对MyBatis缓存的扩展。1.考察你的MyBatis中缓存架构的理解。mybatis 内存采用装饰器模式。

weixin_44416039的博客 492

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Mybatis-缓存详解

存在内存中的临时数据将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题经常查询且不经常改变的数据适合使用缓存。

m0_73856804的博客 1689

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

mybatis缓存的使用及理解

和hibernate一样,mybatis也有缓存机制 一级缓存是基于 PerpetualCache(mybatis自带)的 HashMap 本地缓存,作用范围为session,所以当session commit或close后,缓存就会被清空 二级缓存默认也是基于 PerpetualCache,但是可以为其制定存储源,比如ehcache 一级缓存缓存的是SQL语句,而二级缓存缓存的是...

u011798679的专栏 357

Mybatis的拓展

ResultMap复杂使用 对象关系 分为一对一和一对多,分别使用resultMap提供的不同方案来处理: 一对一:使用association + javaType 一对多:使用collection + ofType pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSch

cgblpx的博客 5352

mybatis二级缓存扩展-与redis集成

  Mybatis为了方便我们扩展缓存定义了一个Cache接口,看看ehcache-mybatis的源码就明白了。我们要使用自己的cache同样的实现Cache接口即可   &lt;cache type="cn.mgr.cache.RedisLoggingCache"/&gt;   public class RedisCache implements Cache {      priv...

zw7534313的专栏 259

springboot mybatis使用redis作为二级缓存

创建springboot项目引入如下依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redi...

letterss的博客 504

MyBatis学习笔记9——MyBatis插件开发

Mybatis 允许在映射语句执行过程中的某一点进行拦截调用。 默认情况下,Mybatis允许使用插件来拦截的接口和方法包括以下几个: 序号 接口 方法 描述 1 Executor update、query、flushStatements、commit、rollback、getTransaction、close、isClosed 拦截执行器的方法 2 ParameterHand...

Willow的博客 2415

MyBatis-Plus(四)~使用过程中的配置选项(进阶配置)

二、进阶配置 本部分(Configuration)的配置大都为 MyBatis 原生支持的配置,这意味着您可以通过 MyBatis XML 配置文件的形式进行配置。 (1)、mapUnderscoreToCamelCase 类型:boolean 默认值:true ...

chengxi2031的博客 1666

Mybatis配置文件解析

对MyBatis的配置文件进行解读

Common的博客 604

SSM 集成redis实现缓存

SSM整合Redis   1.使用maven导入包    org.springframework.data spring-data-redis 1.8.4.RELEASE redis.clients jedis 2.9.0 org.mybatis.caches mybatis-eh

分享我的点点滴滴,在成长路上与你同行! 477

Spring Boot第八章-数据缓存Cache

Spring Boot缓存,本实例尝试了默认缓存,ehcache缓存,redis缓存

有情怀的程序员的博客 1869

redis缓存数据

=======MyBatis缓存使用说明=========== 1, 在应用的服务中sping-context.xml import 引入  spring-jedis.xml 先将 spring-jedis.xml 考过去 2, 目前设置 redis默认缓存 时间为1个小时。 3, 在SQLMap.xml 文件中添加了 缓存实现类才能生效如下:   具体 可以看 wusc.edu.pa

470
上一篇: redis del命令支持正则删除(pattern)
下一篇: mysql中You can't specify target table for update in FROM clause错误
hxpjava1
博客等级 码龄19年 1365粉丝 511原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hxpjava1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值