欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-21 14:37:54
...

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默认为二进制格式)
查询已删除内容
mybatis+springboot整合redis实现缓存查询(解决@Cacheable默认为二进制格式)

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;
        }
    }
相关标签: 学习记录 redis