mybatis+springboot整合redis实现缓存查询(解决@Cacheable默认为二进制格式)

1.导入依赖

 <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--mybatis起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--返回json字符窜的支持  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
#添加项目名
server.servlet.context-path=/redis
server.port=80


#数据库连接信息(useUnicode=true&characterEncoding=UTF-8不加中文查询不到)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cloud?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8

#配置mybatis
#别名扫描包
mybatis.type-aliases-package=com.dxf.redis.pojo
mybatis.mapper-locations=classpath:mapper/*Mapper.xml


#redis配置
#Redis服务器地址
spring.redis.host=127.0.0.1
#Redis服务器连接端口
spring.redis.port=6379
spring.redis.password=myroot
#Redis数据库索引(默认为0)
spring.redis.database=0  
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=50
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=3000
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
#连接超时时间(毫秒)
spring.redis.timeout=5000

logging.level.com.dxf.redis.mapper:debug

2.RedisConfig

在此省略mapper和实体类
//注意实体类实现序列化

public class User implements Serializable {

@Configuration
@EnableCaching //开启spring缓存注解
public class RedisConfig  extends CachingConfigurerSupport {

    /**
     * 自定义生成key的规则
     */
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                //格式化缓存key字符串
                StringBuilder sb = new StringBuilder();
                //追加类名
                sb.append(o.getClass().getName());
                //追加方法名
                sb.append(method.getName());
                //遍历参数并且追加
                for (Object obj : objects) {
                    sb.append(obj.toString());
                }
                System.out.println("调用Redis缓存Key : " + sb.toString());
                return sb.toString();
            }
        };
    }

   /**
    * @Description: 使用@Cacheable注解的时候会将返回的对象缓存起来,默认缓存的值是二进制的,
    * 为此我们自定义序列化配置,改成JSON格式的
    * @Auther: dxf
    * @Date: 20:31 2020/5/20
    */
    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1))// 设置缓存有效期一小时
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }

    /**
     *自己的RedisTemplate
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(factory);
        //序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);过时
                om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }


}

3.UserServiceImpl

几个关键注解

1,@Cacheable

标注在方法上, 将方法返回的结果存入缓存中

可以指定 cachename 或 value 来对 ConcurrentMapCache 的 name 属性进行设置

也可以通过指定 keyGenerator 来制定缓存键值对中生成 key 的规则

默认情况: name 为传入的参数, 键值对中的值为方法返回结果

2,@CachePut

标注在方法上, 先执行方法, 再用方法返回的值来更新缓存内容

3,@CacheEvict

清除缓存

4,@Caching

复杂的 cache 配置, 可以在里面配置上面的几个注解

5,@CacheConfig

标注在类上, 对类中的缓存操作作统一配置

@Service
public class UserServiceImpl implements UserService {

    @Resource
    UserMapper userMapper;

    @Cacheable(value = "user")
    @Override
    public User getUserById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public int insUser(User user) {
        return userMapper.insertSelective(user);
    }

    @CacheEvict(value = "user",allEntries = true)
    @Override
    public int delUserById(Integer id) {
        return userMapper.deleteByPrimaryKey(id);
    }

    @CacheEvict(value = "user",allEntries = true)
    @Override
    public int updUser(User user) {
        return userMapper.updateByPrimaryKeySelective(user);
    }
}

成功
mybatis+springboot整合redis实现缓存查询(解决@Cacheable默认为二进制格式)_第1张图片
查询已删除内容
mybatis+springboot整合redis实现缓存查询(解决@Cacheable默认为二进制格式)_第2张图片

4.修改版


    //@Cacheable(value = "user")
    @Cacheable(value = "user_details", key = "#id", unless="#result == null")
    @Override
    public User getUserById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    //@CacheEvict(value = "user",allEntries = true)
    @CacheEvict(value = "user_details", key = "#id")
    @Override
    public int delUserById(Integer id) {
        return userMapper.deleteByPrimaryKey(id);
    }

    //@CacheEvict(value = "user",allEntries = true)
    @CachePut(value = "user_details", key = "#user.id")
    @Override
    public User updUser(User user) {
        if(userMapper.updateByPrimaryKeySelective(user)> 0) {
            //返回user填入缓存
            return userMapper.selectByPrimaryKey(user.getId());
        }else{
            return null;
        }
    }

你可能感兴趣的:(学习记录)