第十篇 Spring 集成Redis(上)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 第十篇 Spring 集成Redis(上)

1.spring集成redis

1.1、引入spring-data-redis.jar包:

<!-- spring-redis实现 -->
  <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-redis</artifactId>
        <version>1.3.4.RELEASE</version>
    </dependency>

1.2、redis.properties 配置文件

#访问地址
host=127.0.0.1
#访问端口
port=6379
#注意,如果没有password,此处不设置值,但这一项要保留
password=
 #数据库下标
 dbIndex=0
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。
maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制
maxActive=600
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
maxWait=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
testOnBorrow=true

1.3、spring-redis配置文件(此处包含了数据库和mybatis的配置)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context" 
  xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  xmlns:jee="http://www.springframework.org/schema/jee" 
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:util="http://www.springframework.org/schema/util"
  xmlns:jpa="http://www.springframework.org/schema/data/jpa"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
    http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd">
  <!-- 配置 spring-mybatis.xml -->
  <!-- 读取配置文件 -->
  <util:properties id="redis"
    location="classpath:conf/redis.properties"/>   
  <util:properties id="jdbc"
    location="classpath:conf/jdbc.properties"/> 
  <!-- 配置数据库连接池 -->
  <bean id="dataSource"
    class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"> 
    <property name="driverClassName"
      value="#{jdbc.driver}"/>
    <property name="url"
      value="#{jdbc.url}"/>
    <property name="username"
      value="#{jdbc.user}"/>
    <property name="password"
      value="#{jdbc.password}"/>
    <property name="maxIdle"
      value="#{jdbc.maxIdle}"/>
    <property name="maxWait"
      value="#{jdbc.maxWait}"/>           
    <property name="maxActive"
      value="#{jdbc.maxActive}"/>
    <property name="defaultAutoCommit"
      value="#{jdbc.defaultAutoCommit}"/>
    <property name="defaultReadOnly"
      value="#{jdbc.defaultReadOnly}"/>
    <property name="testOnBorrow"
      value="#{jdbc.testOnBorrow}"/>      
    <property name="validationQuery"
      value="#{jdbc.validationQuery}"/> 
  </bean>
  <!-- 配置MyBatis的 SessionFactory -->
  <bean id="sqlSessionFactory"
    class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource"
       ref="dataSource"/>
    <property name="mapperLocations"
      value="classpath:mapper/*.xml"/>
  </bean>
  <!-- Mapper接口组件扫描 -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" 
      value="com.zzipsun.dao"/>
  </bean>
  <!--  transaction config related... --> 
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"
      ref="dataSource"/>
  </bean>
  <!-- 设置 注解驱动的事务管理  -->
  <tx:annotation-driven 
    transaction-manager="txManager"/>
    <!-- redis config start -->
    <!-- 配置JedisPoolConfig实例 -->
     <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxIdle" value="#{redis.maxIdle}" />
        <property name="maxTotal" value="#{redis.maxActive}" />
        <property name="maxWaitMillis" value="#{redis.maxWait}" />
        <property name="testOnBorrow" value="#{redis.testOnBorrow}" />
    </bean>
   <!--  配置JedisConnectionFactory -->
    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="#{redis.host}" />
        <property name="port" value="#{redis.port}" />
       <!--  <property name="password" value="#{redis.password}" /> -->
        <property name="database" value="#{redis.dbIndex}" />
        <property name="poolConfig" ref="poolConfig" />
    </bean>
    <!-- 配置RedisTemplate -->
     <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory" />
                <!--     如果不配置Serializer,那么存储的时候只能使用String,如果用对象类型存储,那么会提示错误 can't cast to String!!!-->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
        </property>
    </bean> 
    <!--自定义redis工具类,在需要缓存的地方注入此类  -->
    <bean id="redisUtil" class="com.zzipsun.util.RedisUtil">
      <property name="redisTemplate" ref="redisTemplate" />
    </bean>
</beans>

1.4、redis工具类(此处try catch为防止redis宕机等问题时 方法可以继续执行)

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/**
 * 
 * @author 
 * 基于spring和redis的redisTemplate工具类
 * 针对所有的hash 都是以h开头的方法
 * 针对所有的Set 都是以s开头的方法                    不含通用方法
 * 针对所有的List 都是以l开头的方法
 */
@Component("redisUtil")
public class RedisUtil {
  private RedisTemplate<String, Object> redisTemplate;
  public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
    this.redisTemplate = redisTemplate;
  }
  //=============================common============================
  /**
   * 指定缓存失效时间
   * @param key 键
   * @param time 时间(秒)
   * @return
   */
  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 获取过期时间
   * @param key 键 不能为null
   * @return 时间(秒) 返回0代表为永久有效
   */
  public long getExpire(String key){
    return redisTemplate.getExpire(key,TimeUnit.SECONDS);
  }
  /**
   * 判断key是否存在
   * @param key 键
   * @return true 存在 false不存在
   */
  public boolean hasKey(String key){
    try {
      return redisTemplate.hasKey(key);
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
  /**
   * 删除缓存
   * @param key 可以传一个值 或多个
   */
  @SuppressWarnings("unchecked")
  public void del(String ... key){
    if(key!=null&&key.length>0){
      if(key.length==1){
        redisTemplate.delete(key[0]);
      }else{
        redisTemplate.delete(CollectionUtils.arrayToList(key));
      }
    }
  }
  //============================String=============================
  /**
   * 普通缓存获取
   * @param key 键
   * @return 值
   */
  public Object get(String key){
    return key==null?null:redisTemplate.opsForValue().get(key);
  }
  /**
   * 普通缓存放入
   * @param key 键
   * @param value 值
   * @return true成功 false失败
   */
  public boolean set(String key,Object value) {
     try {
      redisTemplate.opsForValue().set(key, value);
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      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){
        redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
      }else{
        set(key, value);
      }
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
  /**
   * 递增
   * @param key 键
   * @param by 要增加几(大于0)
   * @return
   */
  public long incr(String key, long delta){  
    if(delta<0){
      throw new RuntimeException("递增因子必须大于0");
    }
    return redisTemplate.opsForValue().increment(key, delta);
    }
  /**
   * 递减
   * @param key 键
   * @param by 要减少几(小于0)
   * @return
   */
  public long decr(String key, long delta){  
    if(delta<0){
      throw new RuntimeException("递减因子必须大于0");
    }
        return redisTemplate.opsForValue().increment(key, -delta);  
    }  
  //================================Map=================================
  /**
   * HashGet
   * @param key 键 不能为null
   * @param item 项 不能为null
   * @return 值
   */
  public Object hget(String key,String item){
    try {
      return redisTemplate.opsForHash().get(key, item);
    } catch (Exception e) {
      return  null;
    }
  }
  /**
   * 获取hashKey对应的所有键值
   * @param key 键
   * @return 对应的多个键值
   */
  public Map<Object,Object> hmget(String key){
    return redisTemplate.opsForHash().entries(key);
  }
  /**
   * HashSet
   * @param key 键
   * @param map 对应多个键值
   * @return true 成功 false 失败
   */
  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 并设置时间
   * @param key 键
   * @param map 对应多个键值
   * @param time 时间(秒)
   * @return true成功 false失败
   */
    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表中放入数据,如果不存在将创建
   * @param key 键
   * @param item 项
   * @param value 值
   * @return true 成功 false失败
   */
  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表中放入数据,如果不存在将创建
   * @param key 键
   * @param item 项
   * @param value 值
   * @param time 时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
   * @return true 成功 false失败
   */
  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表中的值
   * @param key 键 不能为null
   * @param item 项 可以使多个 不能为null
   */
    public void hdel(String key, Object... item){  
    redisTemplate.opsForHash().delete(key,item);
    } 
    /**
     * 判断hash表中是否有该项的值
     * @param key 键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item){
    return redisTemplate.opsForHash().hasKey(key, item);
    } 
  /**
   * hash递增 如果不存在,就会创建一个 并把新增后的值返回
   * @param key 键
   * @param item 项
   * @param by 要增加几(大于0)
   * @return
   */
  public double hincr(String key, String item,double by){  
        return redisTemplate.opsForHash().increment(key, item, by);
    }
  /**
   * hash递减
   * @param key 键
   * @param item 项
   * @param by 要减少记(小于0)
   * @return
   */
  public double hdecr(String key, String item,double by){  
        return redisTemplate.opsForHash().increment(key, item,-by);  
    }  
  //============================set=============================
  /**
   * 根据key获取Set中的所有值
   * @param key 键
   * @return
   */
  public Set<Object> sGet(String key){
    try {
      return redisTemplate.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 redisTemplate.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 redisTemplate.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 = redisTemplate.opsForSet().add(key, values);
          if(time>0) expire(key, time);
            return count;
        } catch (Exception e) {
          e.printStackTrace();
          return 0;
        }
    }
  /**
   * 获取set缓存的长度
   * @param key 键
   * @return
   */
  public long sGetSetSize(String key){
    try {
      return redisTemplate.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 = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
          e.printStackTrace();
          return 0;
        }
    }
    //===============================list=================================
  /**
   * 获取list缓存的内容
   * @param key 键
   * @param start 开始
   * @param end 结束  0 到 -1代表所有值
   * @return
   */
  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缓存的长度
   * @param key 键
   * @return
   */
  public long lGetListSize(String key){
    try {
      return redisTemplate.opsForList().size(key);
    } catch (Exception e) {
      e.printStackTrace();
      return 0;
    }
  }
  /**
   * 通过索引 获取list中的值
   * @param key 键
   * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
   * @return
   */
  public Object lGetIndex(String key,long index){
    try {
      return redisTemplate.opsForList().index(key, index);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }
  /**
   * 将list放入缓存
   * @param key 键
   * @param value 值
   * @param time 时间(秒)
   * @return
   */
  public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
          e.printStackTrace();
          return false;
        }
    }
  /**
   * 将list放入缓存
   * @param key 键
   * @param value 值
   * @param time 时间(秒)
   * @return
   */
  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放入缓存
   * @param key 键
   * @param value 值
   * @param time 时间(秒)
   * @return
   */
  public boolean lSet(String key, List<Object> value) {
      try {
      redisTemplate.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 {
      redisTemplate.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 {
      redisTemplate.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 = redisTemplate.opsForList().remove(key, count, value);
      return remove;
    } catch (Exception e) {
      e.printStackTrace();
      return 0;
    }
  }
}


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
14天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
40 5
|
15天前
|
XML Java API
Spring Boot集成MinIO
本文介绍了如何在Spring Boot项目中集成MinIO,一个高性能的分布式对象存储服务。主要步骤包括:引入MinIO依赖、配置MinIO属性、创建MinIO配置类和服务类、使用服务类实现文件上传和下载功能,以及运行应用进行测试。通过这些步骤,可以轻松地在项目中使用MinIO的对象存储功能。
|
17天前
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
48 5
|
20天前
|
消息中间件 Java Kafka
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
Spring Boot 与 Apache Kafka 集成详解:构建高效消息驱动应用
32 1
|
1月前
|
消息中间件 NoSQL Java
Spring Boot整合Redis
通过Spring Boot整合Redis,可以显著提升应用的性能和响应速度。在本文中,我们详细介绍了如何配置和使用Redis,包括基本的CRUD操作和具有过期时间的值设置方法。希望本文能帮助你在实际项目中高效地整合和使用Redis。
48 2
|
20天前
|
消息中间件 监控 Java
您是否已集成 Spring Boot 与 ActiveMQ?
您是否已集成 Spring Boot 与 ActiveMQ?
41 0
|
2月前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
117 2
|
1月前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
42 0
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
78 6
|
1月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题