现在为什么网站都打不开了怎么办啊,装修室内设计效果图,惠州网站建设,大地保险网站MyBatis缓存描述
MyBatis提供了两种级别的缓存#xff0c; 分别时一级缓存和二级缓存。一级缓存是SqlSession级别的缓存#xff0c;只在SqlSession对象内部存储缓存数据#xff0c;如果SqlSession对象不一样就无法命中缓存#xff0c;二级缓存是mapper级别的缓存#xff…MyBatis缓存描述
MyBatis提供了两种级别的缓存 分别时一级缓存和二级缓存。一级缓存是SqlSession级别的缓存只在SqlSession对象内部存储缓存数据如果SqlSession对象不一样就无法命中缓存二级缓存是mapper级别的缓存只要使用的Mapper类一样就能够共享缓存。
在查询数据时Mybatis会优先查询二级缓存如果二级缓存没有则查询一级缓存都没有才会进行数据库查询。
Mybatis的一级缓存默认是开启的而二级缓存需要在mapper.xml配置文件内或通过CacheNamespace注解手动开启。
需要注意的是在于Spring进行整合时必须开启事务一级缓存会生效因为不开启缓存的话每次查询都会重新创建一个SqlSession对象因此无法共享缓存。
通过CacheNamespace开启某个Mapper的二级缓存。
Mapper
CacheNamespace
public interface EmployeeMapper extends BaseMapperEmployee {
}开启所有的二级缓存
mybatis-plus:mapper-locations: classpath:mybatis/mapper/*.xmlconfiguration:cache-enabled: trueMybatisPlus整合Redis实现分布式二级缓存
Mybatis内置的二级缓存在分布式环境下存在分布式问题无法使用但是我们可以整合Redis来实现分布式的二级缓存。
1.引入依赖
dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.4.1/version
/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId
/dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.24.3/version
/dependencydependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.8.22/version
/dependency2.配置RedisTemplate
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;Configuration
EnableCaching
public class RedisConfiguration {private static final StringRedisSerializer STRING_SERIALIZER new StringRedisSerializer();private static final GenericJackson2JsonRedisSerializer JACKSON__SERIALIZER new GenericJackson2JsonRedisSerializer();BeanPrimarypublic CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {//设置缓存过期时间RedisCacheConfiguration redisCacheCfg RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(STRING_SERIALIZER)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(JACKSON__SERIALIZER));return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)).cacheDefaults(redisCacheCfg).build();}BeanPrimaryConditionalOnMissingBean(name redisTemplate)public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) {// 配置redisTemplateRedisTemplateString, Object redisTemplate new RedisTemplate();redisTemplate.setConnectionFactory(factory);// key序列化redisTemplate.setKeySerializer(STRING_SERIALIZER);// value序列化redisTemplate.setValueSerializer(JACKSON__SERIALIZER);// Hash key序列化redisTemplate.setHashKeySerializer(STRING_SERIALIZER);// Hash value序列化redisTemplate.setHashValueSerializer(JACKSON__SERIALIZER);// 设置支持事务redisTemplate.setEnableTransactionSupport(true);redisTemplate.afterPropertiesSet();return redisTemplate;}Beanpublic RedisSerializerObject redisSerializer() {//创建JSON序列化器ObjectMapper objectMapper new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);//必须设置否则无法将JSON转化为对象会转化成Map类型objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);return new GenericJackson2JsonRedisSerializer(objectMapper);}
}3.自定义缓存类
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;Slf4j
public class MybatisRedisCache implements Cache {// redisson 读写锁private final RReadWriteLock redissonReadWriteLock;// redisTemplateprivate final RedisTemplate redisTemplate;// 缓存Idprivate final String id;//过期时间 10分钟private final long expirationTime 1000*60*10;public MybatisRedisCache(String id) {this.id id;//获取redisTemplatethis.redisTemplate SpringUtil.getBean(RedisTemplate.class);//创建读写锁this.redissonReadWriteLock SpringUtil.getBean(RedissonClient.class).getReadWriteLock(mybatis-cache-lock:this.id);}Overridepublic void putObject(Object key, Object value) {//使用redis的Hash类型进行存储redisTemplate.opsForValue().set(getCacheKey(key),value,expirationTime, TimeUnit.MILLISECONDS);}Overridepublic Object getObject(Object key) {try {//根据key从redis中获取数据Object cacheData redisTemplate.opsForValue().get(getCacheKey(key));log.debug([Mybatis 二级缓存]查询缓存,cacheKey{},data{},getCacheKey(key), JSONUtil.toJsonStr(cacheData));return cacheData;} catch (Exception e) {log.error(缓存出错,e);}return null;}Overridepublic Object removeObject(Object key) {if (key ! null) {log.debug([Mybatis 二级缓存]删除缓存,cacheKey{},getCacheKey(key));redisTemplate.delete(key.toString());}return null;}Overridepublic void clear() {log.debug([Mybatis 二级缓存]清空缓存,id{},getCachePrefix());Set keys redisTemplate.keys(getCachePrefix():*);redisTemplate.delete(keys);}Overridepublic int getSize() {Long size (Long) redisTemplate.execute((RedisCallbackLong) RedisServerCommands::dbSize);return size.intValue();}Overridepublic ReadWriteLock getReadWriteLock() {return this.redissonReadWriteLock;}Overridepublic String getId() {return this.id;}public String getCachePrefix(){return mybatis-cache:%s.formatted(this.id);}private String getCacheKey(Object key){return getCachePrefix():key;}}4.Mapper接口上开启二级缓存
//开启二级缓存并指定缓存类
CacheNamespace(implementation MybatisRedisCache.class,eviction MybatisRedisCache.class)
Mapper
public interface EmployeeMapper extends BaseMapperEmployee {
}