• spring cache之redis使用示例


    spring cache默认缓存底层是使用CurrentHashMap, 本示例使用redis作为缓存载体

    1. pom.xml依赖

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency> 
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    

     

    2. application.yml配置

    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.gjt.mm.mysql.Driver
        url: jdbc:mysql://120.79.xx.xx:3306/demo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false
        username: root
        password: 123456
      jpa:
        hibernate:
          ddl-auto: update
        show-sql: true
      cache:
        type: redis
      redis:
        host: 120.79.xx.xx
        password: 123456
        port: 6379
        database: 0
        timeout: 600ms
        jedis:
          pool:
            max-active: 8
            max-wait: -1ms
            max-idle: 8
            min-idle: 0
    # 显示 Mybatis 的 SQL
    logging:
      level:
        qinfeng.zheng.springbootredis.repository: debug
    
    mybatis:
      configuration:
        map-underscore-to-camel-case: true
    

    3. RedisConfig配置

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    
    import java.time.Duration;
    
    @Configuration
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    public class RedisConfig {
    
        // https://www.ibm.com/developerworks/cn/java/know-redis-and-use-it-in-springboot-projects/index.html
        @Bean
        public RedisCacheConfiguration cacheConfiguration() {
            return RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofSeconds(600))  // redis缓存过期时间
                    .disableCachingNullValues();
        }
    
        /**
         * spring cache管理者
         *
         * @param factory
         * @return
         */
        @Bean
        public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
            return RedisCacheManager.builder(factory)
                    .cacheDefaults(cacheConfiguration())
                    .transactionAware()
                    .build();
        }
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            // Jackson 序列方式
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            // Jackson 默认自动识别 Public 修饰的成员变量、getter、setter
            // private、protected、public 修饰的成员变量都可以自动识别,无需都指定 getter、setter 或者 public。
            // 参考 https://blog.csdn.net/sdyy321/article/details/40298081
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            // 对于 8 种基本数据类型及其封装类和 String ,其他的类型在序列化的时候带上该类型和值
            // 参考 https://www.jianshu.com/p/c5fcd2a1ab49
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
    
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            // Redis 链接
            template.setConnectionFactory(redisConnectionFactory);
            // Redis Key - Value 序列化使用 Jackson
            template.setKeySerializer(jackson2JsonRedisSerializer);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            // Redis HashKey - HashValue 序列化使用 Jackson
            template.setHashKeySerializer(jackson2JsonRedisSerializer);
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
    
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        @ConditionalOnMissingBean(StringRedisTemplate.class)
        public StringRedisTemplate stringRedisTemplate(
                RedisConnectionFactory redisConnectionFactory) {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    }
    @Entity
    @Table(name = "user", schema = "spring")
    public class User implements Serializable {
        private static final long serialVersionUID = 413797298970501130L;
    
        @Id
        private String username;
        private Byte age;
    
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String userName) {
            this.username = userName;
        }
    
        public Byte getAge() {
            return age;
        }
    
        public void setAge(Byte age) {
            this.age = age;
        }
    }

    持久层即可以使用Mybatis也可以使用JPA

    @Mapper
    public interface UserMapper {
        /**
         * 根据用户名 查询用户信息
         *
         * @param username 用户名
         * @return 用户信息
         */
        @Select("Select username, age From user Where username=#{username}")
        User selectByUsername(String username);
    
        /**
         * 根据用户名更新用户昵称、用户年龄、用户性别 信息
         *
         * @param user 用户信息
         */
        @Update("Update user Set age=#{age} Where username=#{username}")
        void update(User user);
    
    
        /**
         * 根据用户名 删除用户信息
         *
         * @param username 用户名
         */
        @Delete("Delete From user where username=#{username}")
        void delete(String username);
    }
    import io.lettuce.core.dynamic.annotation.Param;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    import qinfeng.zheng.springbootredis.entity.User;
    
    @Repository
    public interface UserRepository  extends JpaRepository<User, String> {
        /**
         * 根据用户查询
         *
         * @param username 用户名
         * @return 用户信息
         */
        User findByUsername(@Param("username") String username);
    }

    缓存操作

    import org.springframework.cache.annotation.CacheConfig;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import qinfeng.zheng.springbootredis.entity.User;
    import qinfeng.zheng.springbootredis.repository.UserMapper;
    import qinfeng.zheng.springbootredis.repository.UserRepository;
    
    import javax.annotation.Resource;
    import java.time.Duration;
    
    @RestController
    @CacheConfig(cacheNames = "users")  // 类级别缓存的一些公共设置
    public class RedisController {
        
        @Resource
        private StringRedisTemplate stringTemplate;
    
        @Resource
        private RedisTemplate<String, User> redisTemplate;
    
        @Resource
        private UserRepository userRepository;
    
        @Resource
        private UserMapper userMapper;
    
        @RequestMapping("/setString")
        public String setString(@RequestParam(value = "key") String key,
                                @RequestParam(value = "value") String value) {
            stringTemplate.opsForValue().set(key, value);
            return "ok";
        }
    
        @RequestMapping("/getString")
        public String getString(@RequestParam(value = "key") String key) {
            return stringTemplate.opsForValue().get(key);
        }
    
        
        @RequestMapping(value = "/setUser")
        public String setUser(@RequestBody User user) {
            redisTemplate.opsForValue().set(user.getUsername(), user, Duration.ofMinutes(1));
            return "ok";
        }
    
        @RequestMapping("/getUser")
        public User getUser(@RequestParam(value = "key") String key) {
            return redisTemplate.opsForValue().get(key);
        }
    
        @RequestMapping("/delUser")
        public User delUser(@RequestParam(value = "key") String key) {
            User user = redisTemplate.opsForValue().get(key);
            redisTemplate.delete(key);
            return user;
        }
    
        
        @RequestMapping("/select")
        @Cacheable(key = "#username")   // 将查询结果添加到redis缓存中,redis中的key= cacheNames + key
        public User select(@RequestParam(value = "username") String username) {
            return userRepository.findByUsername(username);
        }
    
        @RequestMapping("/update")
        @CachePut(key = "#user.username")  // 修改
        public User update(@RequestBody User user) {
            return userRepository.save(user);
        }
    
        @RequestMapping("/delete")
        @CacheEvict(key = "#username")  // 删除 
        public User delete(@RequestParam(value = "username") String username) {
            User user = select(username);
            userRepository.delete(user);
            return user;
        }
    
        @RequestMapping("/deleteAllCache")
        @CacheEvict(allEntries = true)   // 删除所有
        public String deleteAllCache() {
            // 删除所有缓存
            return "OK";
        }
    
        @RequestMapping("/mySelect")
        @Cacheable(value = "users", key = "#username")
        public User mySelect(@RequestParam(value = "username") String username) {
            return userMapper.selectByUsername(username);
        }
    
        @RequestMapping("/myUpdate")
        @CachePut(value = "users", key = "#user.username")
        public User myUpdate(@RequestBody User user) {
            userMapper.update(user);
            return userMapper.selectByUsername(user.getUsername());
        }
    
        @RequestMapping("/myDelete")
        @CacheEvict(value = "users", key = "#username")
        public User myDelete(@RequestParam(value = "username") String username) {
            userMapper.delete(username);
            return userMapper.selectByUsername(username);
        }
    
    }

    最后一步,在启动类上开启Cache操作

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    
    @EnableCaching   // 启用缓存
    @SpringBootApplication
    public class RedisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(RedisApplication.class, args);
        }
    
    }

    完毕!

    感觉使用起来还是挺简单的,只需要添加几个注解即可!

    @Cacheable 
    @CacheEvict
    @CachePut
    

      

  • 相关阅读:
    蛙蛙推荐:一个程序员2012年技术学习总结
    蛙蛙推荐:第一堂编程课提纲
    蛙蛙推荐:笨办法提高代码质量
    蛙蛙推荐:Backbone和seajs搭配最佳实践探讨
    时髦的互联网公司都在用什么技术?
    蛙蛙推荐:让SecureCRT好使起来
    Linux LVM卷组管理 规格严格
    聊聊jdbc statement的fetchSize 规格严格
    老生常谈: Eclipse远程调试 规格严格
    产品经理的34个感想
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/12797871.html
Copyright © 2020-2023  润新知