You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot下Redis与JDBC Template集成方案求助

Redis 与 Spring JDBC Template 集成指南

1. 基础依赖配置

首先在项目中添加Redis和JDBC的核心依赖(以Maven为例):

<dependencies>
    <!-- Spring JDBC Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <!-- Spring Redis Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

2. Redis 配置类

自定义RedisTemplate的序列化配置,避免默认JDK序列化的性能和可读性问题:

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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        // 字符串键序列化器
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);

        // JSON值序列化器
        Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(jsonSerializer);
        template.setHashValueSerializer(jsonSerializer);

        template.afterPropertiesSet();
        return template;
    }
}

3. 自定义缓存工具类

封装Redis的缓存操作,方便和JDBC Template结合使用:

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;

@Component
public class RedisCacheUtil {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisCacheUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    // 获取缓存
    public <T> T get(String key, Class<T> clazz) {
        Object value = redisTemplate.opsForValue().get(key);
        return clazz.cast(value);
    }

    // 存入缓存(带过期时间)
    public void put(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    // 删除缓存
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    // 判断缓存是否存在
    public boolean exists(String key) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }
}

4. 结合 JDBC Template 实现带缓存的 CRUD

以用户表为例,实现DAO层的缓存逻辑:

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.concurrent.TimeUnit;

@Repository
public class UserDao {

    private final JdbcTemplate jdbcTemplate;
    private final RedisCacheUtil redisCacheUtil;

    // 缓存键前缀
    private static final String USER_CACHE_PREFIX = "user:id:";
    // 缓存过期时间(1小时)
    private static final long CACHE_TTL = 1;

    public UserDao(JdbcTemplate jdbcTemplate, RedisCacheUtil redisCacheUtil) {
        this.jdbcTemplate = jdbcTemplate;
        this.redisCacheUtil = redisCacheUtil;
    }

    // 查询用户:先查缓存,再查DB
    public User getUserById(Long id) {
        String cacheKey = USER_CACHE_PREFIX + id;
        // 先尝试从Redis获取
        User user = redisCacheUtil.get(cacheKey, User.class);
        if (user != null) {
            return user;
        }
        // 缓存未命中,查询DB
        String sql = "SELECT id, username, email FROM user WHERE id = ?";
        user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
        // 将结果存入Redis
        redisCacheUtil.put(cacheKey, user, CACHE_TTL, TimeUnit.HOURS);
        return user;
    }

    // 更新用户:先更新DB,再删除缓存
    public int updateUser(User user) {
        String sql = "UPDATE user SET username = ?, email = ? WHERE id = ?";
        int rows = jdbcTemplate.update(sql, user.getUsername(), user.getEmail(), user.getId());
        // 删除对应缓存,避免脏数据
        if (rows > 0) {
            String cacheKey = USER_CACHE_PREFIX + user.getId();
            redisCacheUtil.delete(cacheKey);
        }
        return rows;
    }

    // 删除用户:先删除DB,再删除缓存
    public int deleteUser(Long id) {
        String sql = "DELETE FROM user WHERE id = ?";
        int rows = jdbcTemplate.update(sql, id);
        if (rows > 0) {
            String cacheKey = USER_CACHE_PREFIX + id;
            redisCacheUtil.delete(cacheKey);
        }
        return rows;
    }
}

5. 关键注意事项

  • 缓存键规范:用业务前缀+唯一标识的格式(如user:id:123),避免键冲突
  • 缓存一致性:更新/删除操作必须同步清理对应缓存,或者设置合理的过期时间兜底
  • 批量查询优化:如果需要批量查询,可先批量获取Redis缓存,再对未命中的ID批量查询DB,最后将结果批量存入Redis
  • 异常处理:可在缓存操作中添加异常捕获,避免Redis故障影响DB业务

内容的提问来源于stack exchange,提问作者Devdahcoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:57:55