Java Boot整合Redis案例如何做

wen java案例 29

本文目录导读:

Java Boot整合Redis案例如何做

  1. 环境准备
  2. Redis配置类
  3. Redis工具类
  4. 实体类
  5. Service层
  6. Controller层
  7. 启动类
  8. 测试
  9. 常见问题解决

我来为你详细介绍Java Spring Boot整合Redis的完整案例。

环境准备

添加依赖

<!-- pom.xml -->
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Redis -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- Redis连接池 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    <!-- JSON处理 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>2.0.32</version>
    </dependency>
</dependencies>

配置文件

# application.yml
spring:
  redis:
    # Redis服务器地址
    host: localhost
    # Redis服务器端口
    port: 6379
    # Redis密码(如果没有密码则留空)
    password: 
    # 连接超时时间(毫秒)
    timeout: 10000
    # Redis数据库索引(默认为0)
    database: 0
    # 连接池配置
    lettuce:
      pool:
        # 最大连接数
        max-active: 8
        # 最大阻塞等待时间(负值表示没有限制)
        max-wait: -1
        # 最大空闲连接
        max-idle: 8
        # 最小空闲连接
        min-idle: 0

Redis配置类

package com.example.redis.config;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        // 使用FastJson进行序列化
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        // key采用String的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // value采用FastJson序列化
        template.setValueSerializer(fastJsonRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        // hash的value采用FastJson序列化
        template.setHashValueSerializer(fastJsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

Redis工具类

package com.example.redis.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    // ============================= common ============================
    /**
     * 指定缓存失效时间
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据key获取过期时间
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     */
    public boolean hasKey(String key) {
        try {
            return Boolean.TRUE.equals(redisTemplate.hasKey(key));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
    // ============================ String =============================
    /**
     * 普通缓存获取
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 递增
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    // ================================ Map =================================
    /**
     * HashGet
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,并设置时间
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除hash表中的值
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    // ============================ Set =============================
    /**
     * 根据key获取Set中的所有值
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将数据放入set缓存
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取set缓存的长度
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值为value的
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // =============================== List =================================
    /**
     * 获取list缓存的内容
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取list缓存的长度
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 通过索引获取list中的值
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将list放入缓存
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引修改list中的某条数据
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 移除N个值为value
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

实体类

package com.example.redis.entity;
import java.io.Serializable;
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;
    private String username;
    private String email;
    private Integer age;
    // getter和setter方法
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

Service层

package com.example.redis.service;
import com.example.redis.entity.User;
import com.example.redis.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    @Autowired
    private RedisUtil redisUtil;
    // 缓存前缀
    private static final String USER_CACHE_PREFIX = "user:";
    // 缓存过期时间(秒)
    private static final long CACHE_EXPIRE_TIME = 3600;
    /**
     * 根据ID获取用户信息(带缓存)
     */
    public User getUserById(Long id) {
        String key = USER_CACHE_PREFIX + id;
        // 先从缓存中获取
        User user = (User) redisUtil.get(key);
        if (user != null) {
            System.out.println("从缓存中获取用户信息");
            return user;
        }
        // 模拟从数据库查询
        user = getUserFromDatabase(id);
        if (user != null) {
            // 存入缓存
            redisUtil.set(key, user, CACHE_EXPIRE_TIME);
            System.out.println("从数据库中获取用户信息并存入缓存");
        }
        return user;
    }
    /**
     * 更新用户信息
     */
    public boolean updateUser(User user) {
        // 模拟更新数据库
        boolean success = updateUserToDatabase(user);
        if (success) {
            // 更新缓存
            String key = USER_CACHE_PREFIX + user.getId();
            redisUtil.set(key, user, CACHE_EXPIRE_TIME);
            System.out.println("更新用户缓存");
        }
        return success;
    }
    /**
     * 删除用户缓存
     */
    public void deleteUserCache(Long id) {
        String key = USER_CACHE_PREFIX + id;
        redisUtil.del(key);
        System.out.println("删除用户缓存");
    }
    /**
     * 模拟从数据库查询用户
     */
    private User getUserFromDatabase(Long id) {
        // 这里模拟数据库查询
        User user = new User();
        user.setId(id);
        user.setUsername("user_" + id);
        user.setEmail("user" + id + "@example.com");
        user.setAge((int) (Math.random() * 50 + 20));
        return user;
    }
    /**
     * 模拟更新数据库
     */
    private boolean updateUserToDatabase(User user) {
        // 这里模拟数据库更新操作
        System.out.println("更新数据库中的用户信息");
        return true;
    }
}

Controller层

package com.example.redis.controller;
import com.example.redis.entity.User;
import com.example.redis.service.UserService;
import com.example.redis.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/redis")
public class RedisController {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private UserService userService;
    /**
     * 测试基本操作
     */
    @GetMapping("/test")
    public Map<String, Object> testRedis() {
        Map<String, Object> result = new HashMap<>();
        // 测试String操作
        redisUtil.set("test:key", "Hello Redis");
        String value = (String) redisUtil.get("test:key");
        result.put("string_value", value);
        // 测试设置过期时间
        redisUtil.set("test:expire", "过期数据", 10);
        boolean hasKey = redisUtil.hasKey("test:expire");
        result.put("has_key", hasKey);
        long expire = redisUtil.getExpire("test:expire");
        result.put("expire_time", expire + "秒");
        return result;
    }
    /**
     * 测试缓存用户
     */
    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
    /**
     * 测试更新用户
     */
    @PostMapping("/user/update")
    public String updateUser(@RequestBody User user) {
        boolean success = userService.updateUser(user);
        return success ? "更新成功" : "更新失败";
    }
    /**
     * 测试删除缓存
     */
    @DeleteMapping("/user/cache/{id}")
    public String deleteUserCache(@PathVariable Long id) {
        userService.deleteUserCache(id);
        return "缓存已删除";
    }
    /**
     * 测试分布式锁(模拟秒杀场景)
     */
    @GetMapping("/lock")
    public String testLock() {
        String lockKey = "redis:lock:seckill";
        String requestId = String.valueOf(System.currentTimeMillis());
        // 尝试获取锁
        Boolean locked = redisUtil.set(lockKey, requestId, 30);
        if (Boolean.TRUE.equals(locked)) {
            try {
                // 模拟处理业务
                System.out.println("获取锁成功,处理业务...");
                Thread.sleep(1000);
                return "业务处理成功";
            } catch (InterruptedException e) {
                e.printStackTrace();
                return "业务处理失败";
            } finally {
                // 释放锁
                redisUtil.del(lockKey);
            }
        } else {
            return "获取锁失败,请稍后再试";
        }
    }
    /**
     * 测试计数器
     */
    @GetMapping("/counter")
    public String counter() {
        String key = "redis:counter:visits";
        long count = redisUtil.incr(key, 1);
        return "访问次数: " + count;
    }
}

启动类

package com.example.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class, args);
    }
}

测试

启动Redis服务

# 确保Redis服务已启动
redis-server

运行项目

mvn spring-boot:run

测试接口

# 测试基本操作
curl http://localhost:8080/redis/test
# 测试缓存用户
curl http://localhost:8080/redis/user/1
# 测试更新用户
curl -X POST http://localhost:8080/redis/user/update \
  -H "Content-Type: application/json" \
  -d '{"id":1,"username":"newuser","email":"new@example.com","age":25}'
# 测试删除缓存
curl -X DELETE http://localhost:8080/redis/user/cache/1
# 测试分布式锁
curl http://localhost:8080/redis/lock
# 测试计数器
curl http://localhost:8080/redis/counter

常见问题解决

连接超时

spring:
  redis:
    timeout: 30000  # 增加超时时间
    lettuce:
      pool:
        max-wait: 5000  # 设置最大等待时间

序列化问题

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    // 使用Jackson2JsonRedisSerializer替代FastJson
    Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = 
        new Jackson2JsonRedisSerializer<>(Object.class);
    ObjectMapper om = new ObjectMapper();
    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    jackson2JsonRedisSerializer.setObjectMapper(om);
    // ... 其他配置
}

集群配置

spring:
  redis:
    cluster:
      nodes:
        - 192.168.1.1:6379
        - 192.168.1.2:6379
        - 192.168.1.3:6379
      max-redirects: 3

这样就完成了一个完整的Spring Boot整合Redis的案例,包含了基本配置、工具类、业务使用、缓存管理等常见场景。

抱歉,评论功能暂时关闭!