SpringBoot整合Redis入门之缓存数据的方法

bangongJIAO1@c 发布于 2025-12-02 阅读(2)
目录
  • 前言
    • 为什么要使用Redis呢?
    • 相关依赖
  • 配置
    • 数据库
    • 实体类
  • RedisConfig
    • Mapper
    • Service接口
    • Service实现类
  • 测试Redis
    • Controller

      前言

      Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

      为什么要使用Redis呢?

      举个例子,假如系统中有2千万用户信息,用户信息基本固定,一旦录入很少变动,那么你每次加载所有用户信息时,如果都要请求数据库,数据库编译并执行你的查询语句,这样效率就会低下很多,针对这种信息不经常变动并且数据量。

      较大的情况,通常做法,就是把他加入缓存,每次取数前先去判断,如果缓存不为空,那么就从缓存取值,如果为空,再去请求数据库,并将数据加入缓存,这样大大提高系统访问效率。


      相关依赖

      <!-- springboot版本 -->
      <parent>
      	<groupId>org.springframework.boot</groupId>
      	<artifactId>spring-boot-starter-parent</artifactId>
      	<version>2.2.7.RELEASE</version>
      </parent>
      <!-- 依赖 -->
      <dependencies>
      	<!-- redis -->
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-data-redis</artifactId>
      	</dependency>
      	<!-- 通用池 -->
      	<dependency>
      		<groupId>org.apache.commons</groupId>
      		<artifactId>commons-pool2</artifactId>
      	</dependency>
      	<!-- mysql -->
      	<dependency>
      		<groupId>mysql</groupId>
      		<artifactId>mysql-connector-java</artifactId>
      	</dependency>
      	<!-- mybatis -->
      		<dependency>
      		<groupId>org.mybatis.spring.boot</groupId>
      		<artifactId>mybatis-spring-boot-starter</artifactId>
      		<version>2.1.1</version>
      	</dependency>
      	<!-- 通用mapper -->
      	<dependency>
      		<groupId>tk.mybatis</groupId>
      		<artifactId>mapper-spring-boot-starter</artifactId>
      		<version>2.1.5</version>
      	</dependency>
      	<!-- lombok -->
      	<dependency>
      		<groupId>org.projectlombok</groupId>
      		<artifactId>lombok</artifactId>
      	</dependency>
      	<!-- test -->
      	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-test</artifactId>
      	</dependency>
      </dependencies>
      

      配置

      # 端口
      server:
        port: 9998
      # mysql数据源
      spring:
        datasource:
          username: root
          password: root
          url: jdbc:mysql://127.0.0.1:3306/dbtest?serverTimezone=GMT%2B8
      # redis
        redis:
          host: localhost
          port: 6379
          timeout: 1000
          jedis:
            pool:
              min-idle: 5
              max-idle: 10
              max-wait: -1
      # mybatis
      mybatis:
        mapper-locations: classpath:/mybatis/mapper/*.xml
        type-aliases-package: cn.kgc.entities
      #  开启驼峰命名
        configuration:
          map-underscore-to-camel-case: true
      # log
      logging:
        level:
          cn.kgc: debug
      

      数据库

      SpringBoot整合Redis入门之缓存数据的方法

      #建表
      CREATE TABLE `emp`  (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
        `age` int(11) NULL DEFAULT NULL,
        PRIMARY KEY (`id`) USING BTREE
      ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
      #插入数据
      INSERT INTO `emp` VALUES (1, '张三', 18);
      INSERT INTO `emp` VALUES (2, '李四', 20);
      INSERT INTO `emp` VALUES (3, '王五', 22);
      

      实体类

      Emp

      @Data
      @Table(name = "emp")
      public class Emp implements Serializable {
          @Id
          @GeneratedValue(strategy = GenerationType.IDENTITY)
          private Integer id;
          private String name;
          private Integer age;
      }
      

      RedisConfig

      指定Redis序列化方式

      @Configuration
      public class RedisConfig {
      
          @Bean
          public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
              RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
              redisTemplate.setConnectionFactory(factory);
      
              // 指定kv的序列化方式
              Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
              redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
              redisTemplate.setKeySerializer(new StringRedisSerializer());
      
              return redisTemplate;
          }
      }
      

      Mapper

      Emp的Mapper接口继承tk的Mapper类,泛型为实体类Emp

      public interface EmpMapper extends Mapper<Emp> {
      
      }
      

      Service接口

      业务接口定义add添加和getEmpById根据id查询的方法

      public interface EmpService {
          public void add(Emp emp);
          public Object getEmpById(Integer id);
      }
      

      Service实现类

      先查Redis,Redis没有数据再从数据库中拿数据,同时缓存到Redis中。

      @Service
      @Slf4j
      public class EmpServiceImpl implements EmpService {
      
          @Autowired
          public RedisTemplate redisTemplate;
      
          @Resource
          private EmpMapper empMapper;
      
          @Override
          public void add(Emp emp) {
              empMapper.insert(emp);
          }
      
          @Override
          public  Object getEmpById(Integer id) {
              // 先从缓存获取数据,如果有则直接返回
              //                   如果无,则查询mysql,并将数据设置到缓存
              String key = "user:" + id;
              Object userObj = redisTemplate.opsForValue().get(key);
              if(userObj == null){
                  synchronized (this.getClass()){
                      userObj = redisTemplate.opsForValue().get(key);
                      if(userObj == null ){
                          log.debug("----> 查询数据库..............");
                          // 查数据库
                          Emp emp = empMapper.selectByPrimaryKey(id);
                          redisTemplate.opsForValue().set(key,emp);
                          return emp;
                      }else{
                          log.debug("----> 查询缓存(同步代码块)>>>>>>>>>>>>>>>>>");
                          return userObj;
                      }
                  }
      
              }else{
                  log.debug("----> 查询缓存>>>>>>>>>>>>>>>>>");
              }
              return userObj;
          }
      }
      

      测试Redis

      Redis-Controller

      @RestController
      public class RedisContoller {
          @Autowired
          private RedisTemplate redisTemplate;
      
          @GetMapping("/redis/get/{key}")
          public Object get(@PathVariable("key") String key){
             return  redisTemplate.opsForValue().get(key);
          }
      
          @PostMapping("/redis/set/{key}/{value}")
          public Object set(@PathVariable("key") String key,
                            @PathVariable("value") String value){
              redisTemplate.opsForValue().set(key,value);
              return "set success";
          }
      }
      

      Controller

      Redis+MySQL

      @RestController
      public class EmpController {
          @Autowired
          private EmpService empService;
      
          @PostMapping("/emp")
          public String addEmp(Emp emp){
              empService.add(emp);
              return "add ok";
          }
      
          @GetMapping("/emp/{id}")
          public Object getEmpById(@PathVariable("id") Integer id){
              ExecutorService es = Executors.newFixedThreadPool(200);
              for(int i=0 ;i<500;i++){
                  es.submit(new Runnable() {
                      @Override
                      public void run() {
                          empService.getEmpById(id);
                      }
                  });
              }
              return empService.getEmpById(id);
          }
      }