• SpringBoot--中间件技术-2:整合redis,redis实战小案例,springboot cache,cache简化redis的实现,含代码


    SpringBoot整合Redis

    实现步骤

    1. 导pom文件坐标

      
      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-data-redisartifactId>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    2. yaml主配置文件,配置redis端口号

      spring:
        redis:
          host: localhost
          port: 6379
      
      • 1
      • 2
      • 3
      • 4
    3. 测试类

      字符串专用类:StringRedisTemplate stringRedisTemplate

      @Autowired
      public RedisTemplate redisTemplate;
      @Test
      public void stringTest(){
          // 各种类型支持
          stringRedisTemplate.opsForValue();
          stringRedisTemplate.opsForList();
          stringRedisTemplate.opsForSet();
          stringRedisTemplate.opsForHash();
          stringRedisTemplate.opsForZSet();
      
          // 字符串
          stringRedisTemplate.opsForValue().set("teacher","刘老板");
          String teacher = stringRedisTemplate.opsForValue().get("teacher");
          System.out.println("stringRedisTemplate输出结果"+teacher);
      
          // 操作list列表
          stringRedisTemplate.opsForList().leftPush("tang","李白");
          stringRedisTemplate.opsForList().leftPush("tang","杜甫");
      
          stringRedisTemplate.opsForList().leftPushAll("songAll","欧阳修","苏轼","苏辙");
          List<String> songAll = stringRedisTemplate.opsForList().range("songAll", 0, 2);
          songAll.forEach(System.out::println);
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      对象专用类:RedisTemplate redisTemplate

      @Autowired(required = false)
      public RedisTemplate redisTemplate;
      @Test
      public void redisTemplate(){
          // 各种类型支持
          redisTemplate.opsForValue();
          redisTemplate.opsForList();
          redisTemplate.opsForSet();
          redisTemplate.opsForHash();
          redisTemplate.opsForZSet();
      
          ValueOperations valueOperations = redisTemplate.opsForValue();
          valueOperations.set("panda","花花");
          String panda = (String) valueOperations.get("panda");
          System.out.println(panda);
      
          Student student = new Student(1,"惠晨怡","女");
          redisTemplate.opsForValue().set("stu",student);
          Student student1 = (Student) redisTemplate.opsForValue().get("stu");
          System.out.println(student1);
      
          redisTemplate.opsForList().leftPushAll("animal","狗","猫","龙","鼠");
          List animal = redisTemplate.opsForList().range("animal", 0, 3);
          animal.forEach(System.out::println);
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26

      在可视化页面中查看对象存入的键和值,看不明白,没有可读性,可以使用自定义类

      自定义类实现步骤:

      pom文件导入fastJson

      
      <dependency>
          <groupId>com.alibabagroupId>
          <artifactId>fastjsonartifactId>
          <version>1.2.3version>
      dependency>
      
      <dependency>
          <groupId>com.colobugroupId>
          <artifactId>fastjson-jaxrs-json-providerartifactId>
          <version>0.3.1version>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      添加配置类RedisConfig

      @Configuration
      public class RedisConfig {
      
          @Bean
          public RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
              // 创建自定义模板
              RedisTemplate<Object, Object> template = new RedisTemplate<>();
              //配置json类型的序列化工具
              template.setKeySerializer(new StringRedisSerializer());
              template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
      template.setConnectionFactory(redisConnectionFactory);
              return template;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      测试:装配的redis模板类需要和自定义的同名

      @Autowired
      public RedisTemplate jsonRedisTemplate;
      @Test
      public void test03(){
          jsonRedisTemplate.opsForValue();
          jsonRedisTemplate.opsForList();
          jsonRedisTemplate.opsForSet();
          jsonRedisTemplate.opsForHash();
          jsonRedisTemplate.opsForZSet();
      
          Student student1 = new Student(2,"惠晨怡","男");
          Student student2 = new Student(3,"尚恒通","男");
          Student student3 = new Student(4,"李竟坡","男");
      
          ArrayList<Student> students = new ArrayList<>(Arrays.asList(student1,student2,student3));
      
          jsonRedisTemplate.opsForValue().set("stus",students);
          Object stus = jsonRedisTemplate.opsForValue().get("stus");
          String s = JSON.toJSONString(stus);
          List<Student> list = JSONObject.parseArray(s, Student.class);
          list.forEach(System.out::println);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

    SpringBoot整合Redis实战案例

    redis在项目中起到缓存作用,案例演示redis在项目中的实现

    1. 导入pom.xml文件

      springboot版本2.7.14

      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
      dependency>
      
      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-testartifactId>
          <scope>testscope>
      dependency>
      
      
      <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.29version>
      dependency>
      
      
      <dependency>
          <groupId>org.mybatis.spring.bootgroupId>
          <artifactId>mybatis-spring-boot-starterartifactId>
          <version>2.0.1version>
      dependency>
      
      
      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-data-redisartifactId>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
    2. yaml配置文件配置数据源和redis

      # 配置数据源
      spring:
        datasource:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/spring?serverTimezone=GMT
          username: root
          password: 123456
      
        # 配置redis
        redis:
          host: localhost
          port: 6379
      
      mybatis:
        configuration:
          map-underscore-to-camel-case: true
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

      用到了mybatis,所以配置了一个自动驼峰映射

    3. Redis自定义模板配置类

      @Component
      public class RedisConfig {
      
          @Bean
          public RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
              RedisTemplate<Object, Object> template = new RedisTemplate<>();
              template.setKeySerializer(new StringRedisSerializer());
              template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
              template.setConnectionFactory(redisConnectionFactory);
              return template;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    4. 导入redisUtil工具类,工具栏中封装了大量redis操作代码,一般真实开发环境中都可以看到一个公司自己封装的RedisUtil

      @Component
      public  class RedisUtil {
      
          @Autowired(required = false)
          private RedisTemplate jsonRedisTemplate;
      
          // =========================================================
          /**
           * 指定缓存失效时间
           * @param key  键
           * @param time 时间(秒)
           */
          public boolean expire(String key, long time) {
              try {
                  if (time > 0) {
                      jsonRedisTemplate.expire(key, time, TimeUnit.SECONDS);
                  }
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
          /**
           * 根据key 获取过期时间
           * @param key 键 不能为null
           * @return 时间(秒) 返回0代表为永久有效
           */
          public long getExpire(String key) {
              return jsonRedisTemplate.getExpire(key, TimeUnit.SECONDS);
          }
      
      
          /**
           * 判断key是否存在
           * @param key 键
           * @return true 存在 false不存在
           */
          public boolean hasKey(String key) {
              try {
                  return jsonRedisTemplate.hasKey(key);
              } catch (Exception e) {
                  return false;
              }
          }
      
      
          /**
           * 删除缓存
           * @param key 可以传一个值 或多个
           */
          @SuppressWarnings("unchecked")
          public void del(String... key) {
              if (key != null && key.length > 0) {
                  if (key.length == 1) {
                      jsonRedisTemplate.delete(key[0]);
                  } else {
                      jsonRedisTemplate.delete(CollectionUtils.arrayToList(key));
                  }
              }
          }
      
      
          // ============================String=============================
      
          /**
           * 普通缓存获取
           * @param key 键
           * @return 值
           */
          public Object get(String key) {
              return key == null ? null : jsonRedisTemplate.opsForValue().get(key);
          }
      
          /**
           * 普通缓存放入
           * @param key   键
           * @param value 值
           * @return true成功 false失败
           */
      
          public boolean set(String key, Object value) {
              try {
                  jsonRedisTemplate.opsForValue().set(key, value);
                  return true;
              } catch (Exception e) {
                  return false;
              }
          }
      
      
          /**
           * 普通缓存放入并设置时间
           * @param key   键
           * @param value 值
           * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
           * @return true成功 false 失败
           */
      
          public boolean set(String key, Object value, long time) {
              try {
                  if (time > 0) {
                      jsonRedisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                  } else {
                      set(key, value);
                  }
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * 递增
           * @param key   键
           * @param delta 要增加几(大于0)
           */
          public long incr(String key, long delta) {
              if (delta < 0) {
                  throw new RuntimeException("递增因子必须大于0");
              }
              return jsonRedisTemplate.opsForValue().increment(key, delta);
          }
      
      
          /**
           * 递减
           * @param key   键
           * @param delta 要减少几(小于0)
           */
          public long decr(String key, long delta) {
              if (delta < 0) {
                  throw new RuntimeException("递减因子必须大于0");
              }
              return jsonRedisTemplate.opsForValue().increment(key, -delta);
          }
      
      
          // ================================Map=================================
      
          /**
           * HashGet
           * @param key  键 不能为null
           * @param item 项 不能为null
           */
          public Object hget(String key, String item) {
              return jsonRedisTemplate.opsForHash().get(key, item);
          }
      
          /**
           * 获取hashKey对应的所有键值
           * @param key 键
           * @return 对应的多个键值
           */
          public Map<Object, Object> hmget(String key) {
              return jsonRedisTemplate.opsForHash().entries(key);
          }
      
          /**
           * HashSet
           * @param key 键
           * @param map 对应多个键值
           */
          public boolean hmset(String key, Map<String, Object> map) {
              try {
                  jsonRedisTemplate.opsForHash().putAll(key, map);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * HashSet 并设置时间
           * @param key  键
           * @param map  对应多个键值
           * @param time 时间(秒)
           * @return true成功 false失败
           */
          public boolean hmset(String key, Map<String, Object> map, long time) {
              try {
                  jsonRedisTemplate.opsForHash().putAll(key, map);
                  if (time > 0) {
                      expire(key, time);
                  }
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * 向一张hash表中放入数据,如果不存在将创建
           *
           * @param key   键
           * @param item  项
           * @param value 值
           * @return true 成功 false失败
           */
          public boolean hset(String key, String item, Object value) {
              try {
                  jsonRedisTemplate.opsForHash().put(key, item, value);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
          /**
           * 向一张hash表中放入数据,如果不存在将创建
           *
           * @param key   键
           * @param item  项
           * @param value 值
           * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
           * @return true 成功 false失败
           */
          public boolean hset(String key, String item, Object value, long time) {
              try {
                  jsonRedisTemplate.opsForHash().put(key, item, value);
                  if (time > 0) {
                      expire(key, time);
                  }
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * 删除hash表中的值
           *
           * @param key  键 不能为null
           * @param item 项 可以使多个 不能为null
           */
          public void hdel(String key, Object... item) {
              jsonRedisTemplate.opsForHash().delete(key, item);
          }
      
      
          /**
           * 判断hash表中是否有该项的值
           *
           * @param key  键 不能为null
           * @param item 项 不能为null
           * @return true 存在 false不存在
           */
          public boolean hHasKey(String key, String item) {
              return jsonRedisTemplate.opsForHash().hasKey(key, item);
          }
      
      
          /**
           * hash递增 如果不存在,就会创建一个 并把新增后的值返回
           *
           * @param key  键
           * @param item 项
           * @param by   要增加几(大于0)
           */
          public double hincr(String key, String item, double by) {
              return jsonRedisTemplate.opsForHash().increment(key, item, by);
          }
      
      
          /**
           * hash递减
           *
           * @param key  键
           * @param item 项
           * @param by   要减少记(小于0)
           */
          public double hdecr(String key, String item, double by) {
              return jsonRedisTemplate.opsForHash().increment(key, item, -by);
          }
      
      
          // ============================set=============================
      
          /**
           * 根据key获取Set中的所有值
           * @param key 键
           */
          public Set<Object> sGet(String key) {
              try {
                  return jsonRedisTemplate.opsForSet().members(key);
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
          }
      
      
          /**
           * 根据value从一个set中查询,是否存在
           *
           * @param key   键
           * @param value 值
           * @return true 存在 false不存在
           */
          public boolean sHasKey(String key, Object value) {
              try {
                  return jsonRedisTemplate.opsForSet().isMember(key, value);
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * 将数据放入set缓存
           *
           * @param key    键
           * @param values 值 可以是多个
           * @return 成功个数
           */
          public long sSet(String key, Object... values) {
              try {
                  return jsonRedisTemplate.opsForSet().add(key, values);
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
          }
      
      
          /**
           * 将set数据放入缓存
           *
           * @param key    键
           * @param time   时间(秒)
           * @param values 值 可以是多个
           * @return 成功个数
           */
          public long sSetAndTime(String key, long time, Object... values) {
              try {
                  Long count = jsonRedisTemplate.opsForSet().add(key, values);
                  if (time > 0)
                      expire(key, time);
                  return count;
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
          }
      
      
          /**
           * 获取set缓存的长度
           *
           * @param key 键
           */
          public long sGetSetSize(String key) {
              try {
                  return jsonRedisTemplate.opsForSet().size(key);
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
          }
      
      
          /**
           * 移除值为value的
           *
           * @param key    键
           * @param values 值 可以是多个
           * @return 移除的个数
           */
      
          public long setRemove(String key, Object... values) {
              try {
                  Long count = jsonRedisTemplate.opsForSet().remove(key, values);
                  return count;
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
          }
      
          // ===============================list=================================
      
          /**
           * 获取list缓存的内容
           *
           * @param key   键
           * @param start 开始
           * @param end   结束 0 到 -1代表所有值
           */
          public List<Object> lGet(String key, long start, long end) {
              try {
                  return jsonRedisTemplate.opsForList().range(key, start, end);
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
          }
      
      
          /**
           * 获取list缓存的长度
           *
           * @param key 键
           */
          public long lGetListSize(String key) {
              try {
                  return jsonRedisTemplate.opsForList().size(key);
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
          }
      
      
          /**
           * 通过索引 获取list中的值
           *
           * @param key   键
           * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
           */
          public Object lGetIndex(String key, long index) {
              try {
                  return jsonRedisTemplate.opsForList().index(key, index);
              } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
          }
      
      
          /**
           * 将list放入缓存
           *
           * @param key   键
           * @param value 值
           */
          public boolean lSet(String key, Object value) {
              try {
                  jsonRedisTemplate.opsForList().rightPush(key, value);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
      
          /**
           * 将list放入缓存
           * @param key   键
           * @param value 值
           * @param time  时间(秒)
           */
          public boolean lSet(String key, Object value, long time) {
              try {
                  jsonRedisTemplate.opsForList().rightPush(key, value);
                  if (time > 0)
                      expire(key, time);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
      
          }
      
      
          /**
           * 将list放入缓存
           *
           * @param key   键
           * @param value 值
           * @return
           */
          public boolean lSet(String key, List<Object> value) {
              try {
                  jsonRedisTemplate.opsForList().rightPushAll(key, value);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
      
          }
      
      
          /**
           * 将list放入缓存
           *
           * @param key   键
           * @param value 值
           * @param time  时间(秒)
           * @return
           */
          public boolean lSet(String key, List<Object> value, long time) {
              try {
                  jsonRedisTemplate.opsForList().rightPushAll(key, value);
                  if (time > 0)
                      expire(key, time);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
          /**
           * 根据索引修改list中的某条数据
           *
           * @param key   键
           * @param index 索引
           * @param value 值
           * @return
           */
      
          public boolean lUpdateIndex(String key, long index, Object value) {
              try {
                  jsonRedisTemplate.opsForList().set(key, index, value);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              }
          }
      
          /**
           * 移除N个值为value
           *
           * @param key   键
           * @param count 移除多少个
           * @param value 值
           * @return 移除的个数
           */
      
          public long lRemove(String key, long count, Object value) {
              try {
                  Long remove = jsonRedisTemplate.opsForList().remove(key, count, value);
                  return remove;
              } catch (Exception e) {
                  e.printStackTrace();
                  return 0;
              }
      
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137
      • 138
      • 139
      • 140
      • 141
      • 142
      • 143
      • 144
      • 145
      • 146
      • 147
      • 148
      • 149
      • 150
      • 151
      • 152
      • 153
      • 154
      • 155
      • 156
      • 157
      • 158
      • 159
      • 160
      • 161
      • 162
      • 163
      • 164
      • 165
      • 166
      • 167
      • 168
      • 169
      • 170
      • 171
      • 172
      • 173
      • 174
      • 175
      • 176
      • 177
      • 178
      • 179
      • 180
      • 181
      • 182
      • 183
      • 184
      • 185
      • 186
      • 187
      • 188
      • 189
      • 190
      • 191
      • 192
      • 193
      • 194
      • 195
      • 196
      • 197
      • 198
      • 199
      • 200
      • 201
      • 202
      • 203
      • 204
      • 205
      • 206
      • 207
      • 208
      • 209
      • 210
      • 211
      • 212
      • 213
      • 214
      • 215
      • 216
      • 217
      • 218
      • 219
      • 220
      • 221
      • 222
      • 223
      • 224
      • 225
      • 226
      • 227
      • 228
      • 229
      • 230
      • 231
      • 232
      • 233
      • 234
      • 235
      • 236
      • 237
      • 238
      • 239
      • 240
      • 241
      • 242
      • 243
      • 244
      • 245
      • 246
      • 247
      • 248
      • 249
      • 250
      • 251
      • 252
      • 253
      • 254
      • 255
      • 256
      • 257
      • 258
      • 259
      • 260
      • 261
      • 262
      • 263
      • 264
      • 265
      • 266
      • 267
      • 268
      • 269
      • 270
      • 271
      • 272
      • 273
      • 274
      • 275
      • 276
      • 277
      • 278
      • 279
      • 280
      • 281
      • 282
      • 283
      • 284
      • 285
      • 286
      • 287
      • 288
      • 289
      • 290
      • 291
      • 292
      • 293
      • 294
      • 295
      • 296
      • 297
      • 298
      • 299
      • 300
      • 301
      • 302
      • 303
      • 304
      • 305
      • 306
      • 307
      • 308
      • 309
      • 310
      • 311
      • 312
      • 313
      • 314
      • 315
      • 316
      • 317
      • 318
      • 319
      • 320
      • 321
      • 322
      • 323
      • 324
      • 325
      • 326
      • 327
      • 328
      • 329
      • 330
      • 331
      • 332
      • 333
      • 334
      • 335
      • 336
      • 337
      • 338
      • 339
      • 340
      • 341
      • 342
      • 343
      • 344
      • 345
      • 346
      • 347
      • 348
      • 349
      • 350
      • 351
      • 352
      • 353
      • 354
      • 355
      • 356
      • 357
      • 358
      • 359
      • 360
      • 361
      • 362
      • 363
      • 364
      • 365
      • 366
      • 367
      • 368
      • 369
      • 370
      • 371
      • 372
      • 373
      • 374
      • 375
      • 376
      • 377
      • 378
      • 379
      • 380
      • 381
      • 382
      • 383
      • 384
      • 385
      • 386
      • 387
      • 388
      • 389
      • 390
      • 391
      • 392
      • 393
      • 394
      • 395
      • 396
      • 397
      • 398
      • 399
      • 400
      • 401
      • 402
      • 403
      • 404
      • 405
      • 406
      • 407
      • 408
      • 409
      • 410
      • 411
      • 412
      • 413
      • 414
      • 415
      • 416
      • 417
      • 418
      • 419
      • 420
      • 421
      • 422
      • 423
      • 424
      • 425
      • 426
      • 427
      • 428
      • 429
      • 430
      • 431
      • 432
      • 433
      • 434
      • 435
      • 436
      • 437
      • 438
      • 439
      • 440
      • 441
      • 442
      • 443
      • 444
      • 445
      • 446
      • 447
      • 448
      • 449
      • 450
      • 451
      • 452
      • 453
      • 454
      • 455
      • 456
      • 457
      • 458
      • 459
      • 460
      • 461
      • 462
      • 463
      • 464
      • 465
      • 466
      • 467
      • 468
      • 469
      • 470
      • 471
      • 472
      • 473
      • 474
      • 475
      • 476
      • 477
      • 478
      • 479
      • 480
      • 481
      • 482
      • 483
      • 484
      • 485
      • 486
      • 487
      • 488
      • 489
      • 490
      • 491
      • 492
      • 493
      • 494
      • 495
      • 496
      • 497
      • 498
      • 499
      • 500
      • 501
      • 502
      • 503
      • 504
      • 505
      • 506
      • 507
      • 508
      • 509
      • 510
      • 511
      • 512
      • 513
      • 514
      • 515
      • 516
      • 517
      • 518
      • 519
      • 520
      • 521
      • 522
      • 523
      • 524
      • 525
      • 526
      • 527
      • 528
      • 529
      • 530
      • 531
      • 532
      • 533
      • 534
      • 535
      • 536
      • 537
      • 538
      • 539
      • 540
      • 541
      • 542
      • 543
      • 544
      • 545
      • 546
      • 547
      • 548
      • 549
      • 550
      • 551
      • 552
      • 553
      • 554
      • 555
      • 556
    5. 实体类POJO

      public class Student {
          private int stuId;
          private String stuName;
          private String stuSex;
          // get,set,构造,toString等
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    6. Dao层:Mapper

      @Mapper
      public interface StudentMapper {
          @Delete("delete from student where stu_id = #{id}")
          public int delete(Integer id);
      
          @Select("select * from student where stu_id = #{id}")
          public Student find(Integer id);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    7. 业务层:

      接口

      public interface IStudentService {
      
          public void delete(int id);
      
          public Student find(int id);
          
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      实现类

      @Service
      public class StudentServiceImp implements IStudentService {
      
          @Autowired(required = false)
          private StudentMapper mapper;
      
          @Autowired
          private RedisUtil redisUtil;
      
          // 删除用户策略:删除数据表中数据,然后删除缓存
          @Override
          public void delete(int id) {
              // 删除数据库
              int res = mapper.delete(id);
              String key = "student:id:"+id;
              // 判断数据库是否删除成功
              if(res != 0){
                  boolean hasKey = redisUtil.hasKey(key);
                  if(hasKey){
                      redisUtil.del(key);
                      System.out.println("删除了缓存中的key:" + key);
                  }
              }
          }
      
          // 获取用户策略:先从缓存中获取用户,没有则取数据表中数据,再将数据写入缓存
          @Override
          public Student find(int id) {
              String key = "student:id:" + id;
      
              //1.1判断key在redis中是否存在
              boolean hasKey = redisUtil.hasKey(key);
              if (hasKey) {
                  //1.2存在缓存则直接获取
                  Object stu = redisUtil.get(key);
                  ObjectMapper change = new ObjectMapper();
                  Student student =   change.convertValue(stu,Student.class);
                  System.out.println("==========从缓存中获得数据=========");
                  System.out.println(student.getStuName());
                  System.out.println("==============================");
                  return student;
              } else {
                  //1.3不存在缓存,先从数据库中获取,在保存至redis,最后返回用户
                  Student student = mapper.find(id);
                  System.out.println("==========从数据表中获得数据=========");
                  System.out.println(student.getStuName());
                  System.out.println("==============================");
                  if (student != null){
                      redisUtil.set(key, student);//写入缓存
                  }
                  return student;
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
    8. 控制器

      @RestController
      public class StudentController {
      
          @Autowired
          IStudentService service;
      
          @RequestMapping("/delete/{id}")
          public Integer delete(@PathVariable("id") int id){
              service.delete(id);
              return id;
          }
      
          @RequestMapping("/find/{id}")
          public Student find(@PathVariable("id") int id){
              Student student = service.find(id);
              return student;
          }
      
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    9. 启动服务,地址栏中测试查看控制台打印结果,(测试时一定要保证redis服务正在运行,否则存不进redis

      第一次访问localhost:8080/find/1显示从数据表中获得的数据,第二次访问显示缓存中获取的数据

      在这里插入图片描述

    SpringBoot Cache

    SpringBoot Cache介绍

    Spring Cache是一个框架, 实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能

    Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。

    CacheManager缓存管理器是Spring提供的各种缓存技术抽象接口

    针对不同的缓存技术需要实现不同的CacheManager:

    CacheManager描述
    EhCacheCacheManager使用EhCache作为缓存技术(Spring Cache框架操作的默认缓存)
    GuavaCacheManager使用Google的GuavaCache作为缓存技术
    RedisCacheManager使用Redis作为缓存技术

    SpringBoot Cache常用注解

    注解说明
    @EnableCaching开启缓存注解功能
    @Cacheable在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
    @CachePut将方法的返回值放到缓存中
    @CacheEvict将一条或多条数据从缓存中删除

    使用步骤:

    1. 引入缓存启动器:spring-boot-starter-cache,spring-boot-starter-data-redis

    2. @EnableCaching:在启动类上,开启基于注解的缓存

    3. @Cacheable : 标在方法上,返回的结果会进行缓存

    属性: value/cacheNames缓存的名字

    ​ key : 作为缓存中的Key值,可自已使用 SpEL表达式指定(不指定就是参数值), 缓存结果是

    ​ 方法返回值

    名字描述示例
    methodName当前被调用的方法名#root.methodName
    target当前被调用的目标对象#root.target
    targetClass当前被调用的目标对象类#root.targetClass
    args当前被调用的方法的参数列表#root.args[0]
    caches当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”,“cache2”})),则有两个cache#root.caches[0].name
    argument name方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的形式,0代表参数的索引;#iban 、 #a0 、 #p0
    result方法执行后的返回值(仅当方法执行之后的判断有效,在@CachePut 使用于更新数据后可用)#result

    SpringBoot Cache案例简化Redis

    代码实现演示:

    1. pom文件导坐标

      
      <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-data-redisartifactId>
      dependency>
      
      <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-cacheartifactId>
      dependency>
      
      <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-webartifactId>
      dependency>
      <dependency>
         <groupId>org.mybatis.spring.bootgroupId>
         <artifactId>mybatis-spring-boot-starterartifactId>
         <version>2.0.1version>
      dependency>
      
      <dependency>
         <groupId>mysqlgroupId>
         <artifactId>mysql-connector-javaartifactId>
         <scope>runtimescope>
      dependency>
      <dependency>
         <groupId>org.springframework.bootgroupId>
         <artifactId>spring-boot-starter-testartifactId>
         <scope>testscope>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
    2. yaml或properties主配置文件

      spring.datasource.username=root
      spring.datasource.password=123456
      spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
      spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=GMT%2B8
      
      #开启日志管理,可以查看sql语句
      logging.level.com.apesource.springboot_redis03.mapper=debug
      debug=true
      
      #配置要连接redis的地址
      spring.redis.host=localhost
      spring.redis.port=6379
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    3. POJO实体类

      根据要操作的表写,演示为student

      public class Student implements Serializable{
      
          private Integer stuId;
      
          private String stuName;
      
          private String stuSex;
      
          // get、set、toString、有参、无参构造
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    4. Dao层StudentMapper

      public interface StudentMapper {
      
          @Select("select * from Student where stu_id = #{id}")
          public Student getStudentById(Integer id);
      
      
          @Delete("delete from student where stu_id = #{id}")
          public int deleteStudentById(Integer id);
      
          @Update("update student  set stu_name=#{stuName},stu_sex=#{stuSex} where stu_id = #{stuId}")
          public int updateById(Student student);
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    5. Service层

      演示Cache简化redis实现,业务直接写实现类,没写接口

      @Service
      public class StudentService {
      
      
          @Autowired(required = false)
          StudentMapper mapper;
      
      
      
          //根据@Cacheable注解中的cacheNames+key拼接后的值为key
          @Cacheable(cacheNames = "students",key = "#id")
          public Student findById(Integer id){
              return mapper.getStudentById(id);
          }
      
      
          @CacheEvict(cacheNames = "students",key = "#id")
          public void deleteStudentById(Integer id){
              mapper.deleteStudentById(id);
          }
      
          @CachePut(cacheNames = "students",key = "#result.stuId")
          public Student updateById(Student student){
              mapper.updateById(student);
              return student;
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28

      在业务层的方法中,加SpringBoot Cache的注解:

      cacheNames会在缓存中开辟一块儿叫"students"的空间,以键值对的形式存放数据,键是cacheNames+key拼接组成,value就是被标注注解的方法返回值

    6. 控制器StudentController

      @RestController
      public class UserController {
      
          @Autowired
          StudentService userService;
      
          @GetMapping("/findById/{id}")
          public Student findById(@PathVariable("id") Integer id) {
              Student stu = userService.findById(id);
              return stu;
          }
      
      
      
          @GetMapping("/delete/{id}")
          public Integer delete(@PathVariable("id") Integer id) {
              userService.deleteStudentById(id);
              return id;
          }
      
          @GetMapping("/update/{id}/{name}/{hobby}")
          public Integer update(@PathVariable Integer id,@PathVariable String name,@PathVariable String sex) {
              userService.updateById(new Student(id,name,sex));
              return id;
          }
      
      }	
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
    7. 启动类上添加注解

      @SpringBootApplication
      @MapperScan("com.apesource.springboot_redis03")
      @EnableCaching
      public class SpringbootRedis03Application {
      
         public static void main(String[] args) {
            SpringApplication.run(SpringbootRedis03Application.class, args);
         }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    8. 启动服务,浏览器访问localhost:8080/findById/1,访问之后刷新再次访问

      注意启动程序服务之前,需要先把redis运行起来

      在这里插入图片描述

      第一次访问时,从数据库中获取的数据

      第二次访问,没有SQL语句,但是也得到了数据,证明cache实现了缓存的作用

  • 相关阅读:
    计算机毕业设计(附源码)python在线学习平台
    [贪心算法]Leetcode738. 单调递增的数字
    Git报错:git@github.com: Permission denied (publickey)
    java-net-php-python-ssm巴音学院本科部校园网站计算机毕业设计程序
    怎样找外企/远程的工作
    Fiddler工具 — 18.Fiddler抓包HTTPS请求(一)
    NVIDIA NCCL 源码学习(十一)- ring allreduce
    编程老手如何在autojs和冰狐智能辅助之间选择?
    Hbase基本操作---idea连接hbase(shell脚本 springBoot整合Hbase)
    【spring boot 使用模板引擎】
  • 原文地址:https://blog.csdn.net/HakerDONG/article/details/134356274