• SpringBoot3整合Redis&基础操作


    SpringBoot3整合Redis&基础应用

    配套视频:SpringBoot3整合Redis&基础操作视频

    1. 概述

    SpringBoot是一种用于构建Java应用程序的开发框架,Redis是一个高性能的键值存储数据库,常用于缓存、会话管理、消息队列等应用场景,本文将给大家介绍,基于最新的的SpringBoot3基础上如何集成Redis,并实现Redis基本应用操作。

    环境准备

    • Java17 或更高
    • Redis,版本无要求

    2. 整合过程

    1. 创建项目

    2. Maven依赖

      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
      dependency>
      
      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-data-redisartifactId>
      dependency>
      
      <dependency>
          <groupId>com.mysqlgroupId>
          <artifactId>mysql-connector-jartifactId>
      dependency>
      
      <dependency>
          <groupId>org.projectlombokgroupId>
          <artifactId>lombokartifactId>
          <optional>trueoptional>
      dependency>
      <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-testartifactId>
          <scope>testscope>
      dependency>
      
      <dependency>
          <groupId>com.baomidougroupId>
          <artifactId>mybatis-plus-boot-starterartifactId>
          <version>3.5.5version>
      dependency>
      
      <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatis-springartifactId>
          <version>3.0.3version>
      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
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
    3. yml依赖,注意先创建好一个数据库testdb

      server:
        port: 9999
      
      spring:
        data:
          redis:
            host: localhost
            port: 6379
        datasource:
          username: root
          password: 123456
          url: jdbc:mysql:///testdb        
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    4. Redis配置

      @Configuration
      @EnableCaching
      public class RedisConfig {
      
          @Bean
          public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
              RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
              redisTemplate.setConnectionFactory(factory);
              
              redisTemplate.setKeySerializer(new StringRedisSerializer());
              redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
              
              redisTemplate.setHashKeySerializer(new StringRedisSerializer());
              redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
      
              return redisTemplate;
          }
          
          @Bean
          public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
              RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
              RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                      .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
              return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
          }
      }
      
      • 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

    3. RedisTemplate操作

    使用RedisTemplate进行常见的Redis操作,如存储、检索和删除数据。

    1. String

      // 普通字符串
      String key1 = "user:token:0001";
      redisTemplate.opsForValue().set(key1, UUID.randomUUID().toString(), 30, TimeUnit.MINUTES);
      System.out.println(redisTemplate.opsForValue().get(key1));
      
      // 计数
      String key2 = "article:A00001:viewsCount";
      redisTemplate.opsForValue().increment(key2);
      System.out.println(redisTemplate.opsForValue().get(key2));
      
      // 对象
      HashMap<String, Object> user = new HashMap<>();
      user.put("id", "0001");
      user.put("name", "张三疯");
      user.put("age", 28);
      user.put("birthday", new Date(2008 - 1900, 10, 03));
      String key3 = "user:0001";
      redisTemplate.opsForValue().set(key3, user);
      System.out.println(redisTemplate.opsForValue().get(key3));
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    2. hash

      String key4 = "user:0001:cart";
      Map<String, Object> shoppingCart = new HashMap<>();
      shoppingCart.put("cartId", "123456789");
      shoppingCart.put("userId", "987654321");
      
      List<Map<String, Object>> items = List.of(
          Map.of("itemId", "1", "itemName", "手机", "price", 999.99, "quantity", 1),
          Map.of("itemId", "2", "itemName", "笔记本电脑", "price", 1499.99, "quantity", 2),
          Map.of("itemId", "3", "itemName", "耳机", "price", 49.99, "quantity", 3)
      );
      
      shoppingCart.put("items", items);
      shoppingCart.put("totalAmount", 3149.92);
      shoppingCart.put("creationTime", "2046-03-07T10:00:00");
      shoppingCart.put("lastUpdateTime", "2046-03-07T12:30:00");
      shoppingCart.put("status", "未结账");
      
      redisTemplate.opsForHash().putAll(key4, shoppingCart);
      System.out.println(redisTemplate.opsForHash().get(key4, "items"));
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    3. set

      String key5 = "author:0001:fans";
      redisTemplate.opsForSet().add(key5, "张三", "李四", "王五");
      System.out.println("粉丝数:" + redisTemplate.opsForSet().size(key5));
      
      • 1
      • 2
      • 3
    4. zset

      String key5 = "user:0001:friends";
      redisTemplate.opsForZSet().add(key5,"张三", System.currentTimeMillis());
      redisTemplate.opsForZSet().add(key5,"李四", System.currentTimeMillis());
      redisTemplate.opsForZSet().add(key5,"王五", System.currentTimeMillis());
      
      Set<String> friendList  = redisTemplate.opsForZSet().reverseRange(key5, 0L, -1L);
      System.out.println("好友列表:" + friendList );
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    5. list

      String key6 = "order:queue";
      Map<String, Object> order1 = new HashMap<>();
      order1.put("orderId", "1001");
      order1.put("userId", "2001");
      order1.put("status", "已完成");
      order1.put("amount", 500.75);
      order1.put("creationTime", "2024-03-07T09:30:00");
      order1.put("lastUpdateTime", "2024-03-07T10:45:00");
      order1.put("paymentMethod", "在线支付");
      order1.put("shippingMethod", "自提");
      order1.put("remarks", "尽快处理");
      
      Map<String, Object> order2 = new HashMap<>();
      order2.put("orderId", "1002");
      order2.put("userId", "2002");
      order2.put("status", "待处理");
      order2.put("amount", 280.99);
      order2.put("creationTime", "2024-03-07T11:00:00");
      order2.put("lastUpdateTime", "2024-03-07T11:00:00");
      order2.put("paymentMethod", "货到付款");
      order2.put("shippingMethod", "快递配送");
      order2.put("remarks", "注意保鲜");
      // A程序接收订单请求并将其加入队列
      redisTemplate.opsForList().leftPush(key6,order1);
      redisTemplate.opsForList().leftPush(key6,order2);
      // B程序从订单队列中获取订单数据并处理
      System.out.println("处理订单:" + redisTemplate.opsForList().rightPop(key6));
      
      • 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

    4. @RedisHash注解

    @RedisHash:用于将Java对象映射到Redis的Hash数据结构中,使得对象的存储和检索变得更加简单

    1. 创建实体类

      @Data
      @RedisHash
      public class User {
          @Id
          private Integer id;
          private String name;
          private Integer age;
          private String phone;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    2. 创建接口,注意需要继承CrudRepository,这样改接口就具备对应实体的redis中的增删改查操作

      public interface UserRedisMapper extends CrudRepository<User,Integer> {
      }
      
      • 1
      • 2
    3. 操作

      @Autowired
      private UserRedisMapper userRedisMapper;
      
      @Test
      public void testRedisHash(){
          User user = new User();
          user.setId(100);
          user.setName("张三疯");
          user.setAge(18);
          user.setPhone("19988889999");
          // 保存
          userRedisMapper.save(user);
          // 读取
          User redisUser = userRedisMapper.findById(100).get();
          System.out.println("redisUser:" + redisUser);
          // 更新
          user.setPhone("18899998888");
          userRedisMapper.save(user);
          // 删除
          //userRedisMapper.deleteById(100);
          // 判断存在
          boolean exists = userRedisMapper.existsById(100);
          System.out.println("exists: " + exists);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24

    5. 缓存管理注解

    Spring的缓存管理功能旨在帮助开发人员轻松地在应用程序中使用缓存,以提高性能和响应速度。它提供了一套注解和配置,使得开发人员可以在方法级别上进行缓存控制,并且支持多种缓存存储提供程序,如Caffeine、EhCache、Redis等。

    注解说明
    @Cacheable用于声明一个方法的返回值应该被缓存起来,以便下次相同的参数调用时可以直接返回缓存中的值,而不需要执行方法体。
    @CachePut用于更新缓存中的数据,它会在方法执行后,将返回值更新到缓存中
    @CacheEvict用于清除缓存中的数据,它可以根据条件清除指定的缓存项
    1. 准备表

      CREATE TABLE product (
          id INT AUTO_INCREMENT PRIMARY KEY,
          name VARCHAR(255) NOT NULL,
          description TEXT,
          price DECIMAL(10, 2) NOT NULL,
          stock INT NOT NULL
      );
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      INSERT INTO product (name, description, price, stock) VALUES
      ('iPhone 15', '最新的iPhone型号', 8999.99, 100),
      ('三星Galaxy S24', '旗舰安卓手机', 7899.99, 150),
      ('MacBook Pro', '专业人士的强大笔记本电脑', 15999.99, 50),
      ('iPad Air', '性能强劲的便携式平板电脑', 5599.99, 200),
      ('索尼PlayStation 6', '下一代游戏机', 4499.99, 75);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    2. 实体类

      @Data
      @TableName
      public class Product {
          @TableId
          private Integer id;
          private String name;
          private String description;
          private Double price;
          private Integer stock;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    3. Mapper

      public interface ProductMapper extends BaseMapper<Product> {
      }
      
      • 1
      • 2

      启动类添加注解 @MapperScan(“com.qqcn.*.mapper”)

    4. Service

      public interface ProductService {
          // 根据商品ID获取商品信息
          Product getProductById(Integer id);
      
          // 添加新商品
          Product addProduct(Product product);
      
          // 更新商品信息
          Product updateProduct(Product product);
      
          // 根据商品ID删除商品
          Integer deleteProductById(Integer id);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      @Service
      public class ProductServiceImpl implements ProductService {
      
          @Resource
          private ProductMapper productMapper;
      
          @Cacheable(value = "product", key = "'product:' + #id")
          @Override
          public Product getProductById(Integer id) {
              return productMapper.selectById(id);
          }
      
          @CachePut(value = "product", key = "'product:' + #product.id")
          @Override
          public Product addProduct(Product product) {
              productMapper.insert(product);
              return product;
          }
      
          @CachePut(value = "product", key = "'product:' + #product.id")
          @Override
          public Product updateProduct(Product product) {
              productMapper.updateById(product);
              return product;
          }
      
          @CacheEvict(value = "product", key = "'product:' + #id")
          @Override
          public Integer deleteProductById(Integer id) {
              productMapper.deleteById(id);
              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
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
    5. 测试

      @Autowired
      private ProductService productService;
      
      @Test
      public void testQuery(){
          Product product = productService.getProductById(1);
          System.out.println(product);
      }
      
      @Test
      public void testUpdate(){
          Product product = productService.getProductById(1);
          System.out.println(product);
          product.setName("苹果19");
          productService.updateProduct(product);
          System.out.println(productService.getProductById(1));
      }
      
      @Test
      public void testDelete(){
          productService.deleteProductById(1);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

    结束语

    以上就是本期分享内容,内容并不全面,旨在抛砖引玉,最重要的还是需要你到项目中,在合适的应用场景中去使用redis,发挥出redis的优势和价值。

  • 相关阅读:
    vite + vue3.0 + ts 项目搭建
    java8 CompletableFuture: 组合式异步编程
    《自然语言处理实战:利用Python理解、分析和生成文本》读书笔记:第2章 构建自己的词汇表——分词
    skywalking监控
    使用MediatR实现CQRS
    线上展厅功能要点
    【LC刷题】DAY24:122 55 45 1005
    代码应该怎么写?
    【车载开发系列】UDS诊断---诊断故障清除($0x14)
    【矩阵论】2. 矩阵分解——单阵及特征值特征向量一些求法
  • 原文地址:https://blog.csdn.net/m0_37613503/article/details/136684258