redis(基础 && redis缓存)

一,redis基础

目录

    1. 数据类型
  • 1.1 字符串
  • 1.2 hash
  • 1.3 List
  • 1.4 Set
  • 1.5 sorted set
    1. jedis操作redis
    1. 与spring集成
  • 数据类型

1.1 字符串

String是最常用的数据格式,普通的 kay-value都归结为此类, value值不仅可以是string,可以是数字。
使用场景:通过用户的访问次数为依据封锁ip,可以将用户的访问次数已string类型记录在redis中,并通过
INCRBY操作,每次访问进行递增(原子性操作 像一些活动秒杀 ,抢红包 应用分布式系统)。
常用命令:
get, set, incr, decr, mget

示例:

set
set name  zhangsan

get
get name

#查看redis所有key
keys *

#查看redis中以name开发的key
keys name*

#设置一个数字
set num 1

#自增
incr num

#递减
decr num

1.2 hash

使用场景:( 保存对象,像一些档案信息可以放入hash) 例如用户包含id,name,addr等属性,当需要使用redis存放用户信息时,可以使用hash。(和java中的Map很像)
常用命令: hget,hset,hgetall等

示例:

 # 以user:001为键,hash中有两个属性name为zs,age为19
 hset user:001 name zs age 19

 #获取以user:001为键,属性age的值
 hget user:001 age

 # 获取键为user:001的所用属性值
 hgetall user:001

1.3 List

应用场景:最新消息排行; 消息队列。利用Lists的push(推入)的操作,将任务存储在list中,然后工作线程再用pop(弹出)操作将任务取出进行执行。

常用命令:
lpush,rpush,lpop,rpop,lrange(范围),BLPOP(阻塞版)等

示例:

向队列中push数据
lpush bills zs li wu zl

#从队列中弹出数据,弹出后队列中的数据不保存
lpop bills

#队列的长度
llen bills

1.4 Set

常用场景: set与list比较类似,特殊之处是set可以自动去重,同时set还提供了某个成员是否存在于一个set内的接口,这个在list也没有。
常用命令:
sadd,srem,spop,sdiff ,smembers,sunion 等

redis(基础 && redis缓存)

示例:

向集合aa中加入1 2 3 4 5
sadd aa 1 2 3 4 5

向集合bb中加入4 5 6 7 8
sadd bb 4 5 6 7 8

返回集合aa中的所有元素
smembers aa

判断集合aa中是否存在元素1  ,存在返回1,不存在返回0
sismember aa 1

#返回aa集合中存在但bb中不存在的元素,返回 1 2 3 (差集)
sdiff aa bb

#求aa和bb集合的差集,并将结果保存到cc中去
sdiffstore cc aa bb

#求aa和bb的交集
sinter aa bb

#求aa和bb的交集,并将其存放到dd集合中去
sinterstore dd aa bb

#求aa和bb的并集
sunion aa bb

#求aa和bb的并集,将将其结果存放如ee集合
sunionstore ee aa bb

从ee集合中弹出3个元素(随机),默认弹出1个元素
spop ee 3

1.5 sorted set(有序集合)

使用场景:zset的使用场景与set类似,区别是set不是有序的,而zset可以通过用户额外提供的一个优先级( score即分值)参数来为成员 ( 进行排名)排序,插入后自动排序。例如:将所有评论按发表时间为score存储,可以方便获取最新发表的评论;全班同学成绩的SortedSets,value可以是同学的学号,而score就可以是其考试得分,这样数据插入集合的,就已经进行了天然的排序。
另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。

常用命令:
zadd,zrange 取出 (可根据范围取出),zrem删除,zcard获取数量,zcount等

示例:

#将zs, ww, ls加入有序集合,其中zs 分值为1, ww 分值为2, ls分值为3
zadd zaa 1 zs 2 ww 3 ls

#获取zaa集合中score值从1到2范围内的元素
zrangebyscore zaa 1 2

#获取有序集合的成员数
zcard zaa

#计算在有序集合中指定区间分数的成员数
zcount zaa 1 2
#判断key在redis中是否存在。
exists key
  1. jedis操作redis

1)创建一个maven工程
File ->New -> maven project -> create a simple project,输入maven坐标。

2) 在pom.xml文件中加jedis依赖

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<dependencies>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<dependency>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<groupid>redis.clients</groupid>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<artifactid>jedis</artifactid>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<version>2.9.0</version>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;</dependency>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;</dependencies>

3)在pom.xml中指定jdk版本

<build>
    <finalname>&#x586B;&#x5199;&#x81EA;&#x5DF1;&#x7684;&#x9879;&#x76EE;&#x540D;&#x79F0;</finalname>
    <plugins>
          <!--第一步就是配置maven-compiler-plugin插件 -->
          <plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-compiler-plugin</artifactid>
                <version>3.7.0</version>
                <configuration>
                      <source>1.8
                      <target>1.8</target>
                      <encoding>UTF-8</encoding>
                </configuration>
          </plugin>
    </plugins>
</build>

3)示例代码


//&#x521B;&#x5EFA;Jedis&#x5B9E;&#x4F8B;&#xFF0C;&#x8FDE;&#x63A5;redis
Jedis jedis = new Jedis("192.168.62.133",6379);

//ping&#xFF0C;&#x5982;&#x679C;&#x6210;&#x529F;&#x8FD4;&#x56DE; pong
String rv = jedis.ping();
System.out.println(rv);

//string
jedis.set("name", "zs");

//hash
jedis.hset("user", "name", "&#x5F20;&#x4E09;");
jedis.hset("user", "age", "20");
jedis.hset("user", "tele", "12344344343");
jedis.hset("user", "addr", "&#x957F;&#x6C99;");

Map<string,string> user = new HashMap<>();
user.put("name", "&#x674E;&#x56DB;");
user.put("age", "23");
user.put("tele", "23897989");
user.put("addr", "&#x6210;&#x90FD;");
jedis.hmset("user02", user);

//list
jedis.lpush("list", "a");
jedis.lpush("list", "b");
jedis.lpush("list", "c");
jedis.lpush("list", "d");

System.out.println(jedis.rpop("list"));
System.out.println(jedis.rpop("list"));
System.out.println(jedis.rpop("list"));
System.out.println(jedis.rpop("list"));

//set
jedis.sadd("set", "aa","bb","cc");
System.out.println(jedis.spop("set"));
System.out.println(jedis.spop("set"));
System.out.println(jedis.spop("set"));

//sortset
Map<string,double> zz = new HashMap<>();
zz.put("zz", 0.1D);
jedis.zadd("zset", zz);

Map<string,double> ff = new HashMap<>();
ff.put("ff", 0.2D);
jedis.zadd("zset", ff);

Map<string,double> qq = new HashMap<>();
qq.put("qq", 0.3D);
jedis.zadd("zset", qq);

System.out.println(jedis.zrangeByScore("zset", 0.1, 0.2));

//&#x547D;&#x4EE4;&#x8FD4;&#x56DE;&#x6709;&#x5E8F;&#x96C6;&#x4E2D;&#xFF0C;&#x6307;&#x5B9A;&#x533A;&#x95F4;&#x5185;&#x7684;&#x6210;&#x5458;, &#x5176;&#x4E2D;&#x6210;&#x5458;&#x7684;&#x4F4D;&#x7F6E;&#x6309;&#x5206;&#x6570;&#x503C;&#x9012;&#x51CF;(&#x4ECE;&#x5927;&#x5230;&#x5C0F;)&#x6765;&#x6392;&#x5217;
System.out.println(jedis.zrevrange("zset", 0, -1));
</string,double></string,double></string,double></string,string>
  1. 与spring集成

1) 在pom.xml文件中导入依赖的包


<properties>
    <!-- redis版本 -->
    <redis.version>2.9.0</redis.version>
    <spring.redis.version>2.0.10.RELEASE</spring.redis.version>
    <spring.version>5.0.1.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
          <groupid>redis.clients</groupid>
          <artifactid>jedis</artifactid>
          <version>${redis.version}</version>
    </dependency>

    <!--2. spring相关(5.0.1.RELEASE) -->
    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-context</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-orm</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-web</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <!-- aop -->
    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-aop</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-test</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <dependency>
          <groupid>org.springframework</groupid>
          <artifactid>spring-aspects</artifactid>
          <version>${spring.version}</version>
    </dependency>

    <dependency>
          <groupid>org.aspectj</groupid>
          <artifactid>aspectjrt</artifactid>
          <version>1.6.11</version>
    </dependency>

    <dependency>
          <groupid>org.aspectj</groupid>
          <artifactid>aspectjweaver</artifactid>
          <version>1.6.11</version>
    </dependency>

    <dependency>
          <groupid>cglib</groupid>
          <artifactid>cglib</artifactid>
          <version>2.1_3</version>
    </dependency>

    <!--spring redis 支持-->
    <dependency>
         <groupid>org.springframework.data</groupid>
         <artifactid>spring-data-redis</artifactid>
         <version>1.7.2.RELEASE</version>
    </dependency>
    <!-- end -->

    <!--当将对象在redis中存储为json时需要-->
    <dependency>
          <groupid>com.fasterxml.jackson.core</groupid>
          <artifactid>jackson-core</artifactid>
          <version>2.1.0</version>
    </dependency>

    <dependency>
          <groupid>com.fasterxml.jackson.core</groupid>
          <artifactid>jackson-databind</artifactid>
          <version>2.1.0</version>
    </dependency>

    <dependency>
          <groupid>com.fasterxml.jackson.core</groupid>
          <artifactid>jackson-annotations</artifactid>
          <version>2.1.0</version>
    </dependency>

    <!--测试-->
    <dependency>
          <groupid>junit</groupid>
          <artifactid>junit</artifactid>
          <version>4.12</version>
          <scope>test</scope>
    </dependency>

</dependencies>

2)spring-redis.xml

<?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:aop="http://www.springframework.org/schema/aop"       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"       xsi:schemalocation="http://www.springframework.org/schema/beans
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/beans/spring-beans.xsd
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; &#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/aop
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; &#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/context
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/context/spring-context-4.3.xsd
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; &#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/tx
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<context:component-scan base-package="com.zking">

&#xA0;&#xA0;&#xA0; <!-- 连接池基本参数配置,类似数据库连接池 -->
&#xA0;&#xA0;&#xA0; <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true">
&#xA0;&#xA0;&#xA0;

&#xA0;&#xA0;&#xA0; <!--redis连接池 -->&#xA0;
&#xA0;&#xA0;&#xA0; <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="maxTotal" value="${redis.maxActive}">
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="maxIdle" value="${redis.maxIdle}">
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="testOnBorrow" value="${redis.testOnBorrow}">
&#xA0;&#xA0;&#xA0; </property></property></property></bean>

&#xA0;&#xA0;&#xA0; <!-- 连接池配置,类似数据库连接池 -->
&#xA0;&#xA0;&#xA0; <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="hostName" value="${redis.host}"></property>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="port" value="${redis.port}"></property>
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <!-- <property name="password" value="${redis.pass}"></property> -->
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="poolConfig" ref="poolConfig"></property>
&#xA0;&#xA0;&#xA0; </bean>

&#xA0;&#xA0;&#xA0; <!--redis操作模版,使用该对象可以操作<u>redis</u>  -->&#xA0;
&#xA0;&#xA0;&#xA0; <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="connectionFactory" ref="jedisConnectionFactory">&#xA0;&#xA0;

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="keySerializer">&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <bean class="org.springframework.data.redis.serializer.StringRedisSerializer">&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </bean></property>&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="valueSerializer">&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer">&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </bean></property>&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="hashKeySerializer">&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <bean class="org.springframework.data.redis.serializer.StringRedisSerializer">
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </bean></property>&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="hashValueSerializer">&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer">&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; </bean></property>&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <!--开启事务  -->&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <property name="enableTransactionSupport" value="true">
        </property>&#xA0;
&#xA0;&#xA0;&#xA0; </property></bean>

</context:property-placeholder></context:component-scan></beans>

3) 测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring*.xml")
@SuppressWarnings("all")
public class TestRedis {

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;@Autowired
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;private RedisTemplate<string, object> redisTemplate;

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;@Test
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;public void testRedis() {
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;redisTemplate.opsForHash().put("myhash", "name", "xiaoxiao");
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;redisTemplate.opsForHash().put("myhash", "age", "12");
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;redisTemplate.opsForHash().put("myhash", "addr", "changsha");
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;Map<object, object> entries = redisTemplate.opsForHash().entries("myhash");

&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;for(Map.Entry e: entries.entrySet()) {
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;System.out.println(e.getKey());
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;System.out.println(e.getValue());
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}
}
</object,></string,>

测试类通过则说明集成完成(请确定redis可正常访问)

二.redis缓存

目录

    1. 作用
    1. 集成
  • 2.1 导入需要的包
  • 2.2 redis的属性配置文件
  • 2.3 spring 与redis集成配置
    • 2.3.1 xml方式
    • 2.3.2 程序方式配置
    1. 使用示例
  • 3.1 @Cacheable
    • 3.1.1 通过指定的key,将查询结果缓存到redis中
    • 3.1.2 配置key的生成策略
    • 3.1.3 condition
  • 3.2 @CacheEvict
  • 3.3 @CachePut
  • 3.4 @Caching
  • 3.5 @CacheConfig

  • 作用

  • 提升系统的运行效率

  • 简化缓存的使用

  • 集成

2.1 导入需要的包

包括jedis,spring-data-redis以及jackson(在将对象序列化保存到redis中需要)

2.2 redis的属性配置文件

redis属性配置文件放在resources目录下

#&#x8BBF;&#x95EE;&#x5730;&#x5740;
redis.host=192.168.62.147
#&#x8BBF;&#x95EE;&#x7AEF;&#x53E3;
redis.port=6379
#&#x6CE8;&#x610F;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;password&#xFF0C;&#x6B64;&#x5904;&#x4E0D;&#x8BBE;&#x7F6E;&#x503C;&#xFF0C;&#x4F46;&#x8FD9;&#x4E00;&#x9879;&#x8981;&#x4FDD;&#x7559;
#redis.password=

#&#x6700;&#x5927;&#x7A7A;&#x95F2;&#x6570;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x7684;&#x6700;&#x5927;&#x7A7A;&#x95F2;&#x65F6;&#x95F4;&#x3002;&#x8D85;&#x8FC7;&#x7A7A;&#x95F2;&#x65F6;&#x95F4;&#xFF0C;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x5C06;&#x88AB;&#x6807;&#x8BB0;&#x4E3A;&#x4E0D;&#x53EF;&#x7528;&#xFF0C;&#x7136;&#x540E;&#x88AB;&#x91CA;&#x653E;&#x3002;&#x8BBE;&#x4E3A;0&#x8868;&#x793A;&#x65E0;&#x9650;&#x5236;&#x3002;
redis.maxIdle=300
#&#x8FDE;&#x63A5;&#x6C60;&#x7684;&#x6700;&#x5927;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x6570;&#x3002;&#x8BBE;&#x4E3A;0&#x8868;&#x793A;&#x65E0;&#x9650;&#x5236;
redis.maxTotal=600
#&#x6700;&#x5927;&#x5EFA;&#x7ACB;&#x8FDE;&#x63A5;&#x7B49;&#x5F85;&#x65F6;&#x95F4;&#x3002;&#x5982;&#x679C;&#x8D85;&#x8FC7;&#x6B64;&#x65F6;&#x95F4;&#x5C06;&#x63A5;&#x5230;&#x5F02;&#x5E38;&#x3002;&#x8BBE;&#x4E3A;-1&#x8868;&#x793A;&#x65E0;&#x9650;&#x5236;&#x3002;
redis.maxWaitMillis=1000
#&#x5728;borrow&#x4E00;&#x4E2A;jedis&#x5B9E;&#x4F8B;&#x65F6;&#xFF0C;&#x662F;&#x5426;&#x63D0;&#x524D;&#x8FDB;&#x884C;alidate&#x64CD;&#x4F5C;&#xFF1B;&#x5982;&#x679C;&#x4E3A;true&#xFF0C;&#x5219;&#x5F97;&#x5230;&#x7684;jedis&#x5B9E;&#x4F8B;&#x5747;&#x662F;&#x53EF;&#x7528;&#x7684;&#xFF1B;
redis.testOnBorrow=true

2.3 spring 与redis集成配置

2.3.1 xml方式

xml配置文件放在resources目录下,已applicationContext-redis.xml命名

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd     http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- 连接池基本参数配置,类似数据库连接池 -->
    <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true">

    <!-- redis连接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.maxTotal}">
        <property name="maxIdle" value="${redis.maxIdle}">
        <property name="testOnBorrow" value="${redis.testOnBorrow}">
    </property></property></property></bean>

    <!-- 连接池配置,类似数据库连接池 -->
    <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}"></property>
        <property name="port" value="${redis.port}"></property>
        <!-- <property name="password" value="${redis.pass}"></property> -->
        <property name="poolConfig" ref="poolConfig"></property>
    </bean>

    <!--redis操作模版,使用该对象可以操作redis  -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="jedisConnectionFactory">
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer">
        </bean></property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer">
        </bean></property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer">
        </bean></property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer">
        </bean></property>
        <!--开启事务  -->
        <property name="enableTransactionSupport" value="true"></property>
    </property></bean>

    <!-- 启用缓存 -->
    <cache:annotation-driven cache-manager="cacheManager">

    <!-- 声明reids缓存管理器 -->
    <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
        <constructor-arg index="0" ref="redisTemplate"></constructor-arg>
        <!-- 用于指明过期时间 -->
        <!--<property name="expires">
            <map>
                <entry key="students" value="#{60*2}"/>
            </map>
        </property>-->

    </bean>

    <bean id="customKeyGenerator" class="com.zking.mybatisdemo.config.CustomKeyGenerator">

</bean></cache:annotation-driven></context:property-placeholder></beans>

2.3.2 程序方式配置

在源码中,可以新建一个config的包,用于放置配置相关的java文件。

@Configuration
@EnableCaching
public class CacheConfig {

    private static final Logger log = LoggerFactory.getLogger(CacheConfig.class);

    @Bean
    public JedisConnectionFactory redisConnectionFactory() throws IOException {

        ClassPathResource resource = new ClassPathResource("/redis.properties");
        InputStream in = resource.getInputStream();
        Properties prop = new Properties();
        prop.load(in);

        String host = prop.getProperty("redis.host");
        Integer port = Integer.valueOf(prop.getProperty("redis.port"));
        Integer maxIdle = Integer.valueOf(prop.getProperty("redis.maxIdle"));
        Integer maxTotal = Integer.valueOf(prop.getProperty("redis.maxTotal"));
        Integer maxWaitMillis = Integer.valueOf(prop.getProperty("redis.maxWaitMillis"));
        boolean testOnBorrow =  Boolean.valueOf(prop.getProperty("redis.testOnBorrow"));

        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxWaitMillis(maxWaitMillis);
        poolConfig.setTestOnBorrow(testOnBorrow);

        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
        redisConnectionFactory.setHostName(host);
        redisConnectionFactory.setPort(port);
        redisConnectionFactory.setPoolConfig(poolConfig);

        return redisConnectionFactory;
    }

    @Bean
    public RedisTemplate<object, object> redisTemplate(RedisConnectionFactory cf) {
        RedisTemplate<object, object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(cf);

        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);

        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        return redisTemplate;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684;&#x8FC7;&#x671F;&#x65F6;&#x95F4;
        cacheManager.setDefaultExpiration(300);
        return cacheManager;
    }

    @Bean
    public KeyGenerator customKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(o.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

}
</object,></object,>
  1. 使用示例

常用注解:

  • @Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
  • @CacheEvict 主要针对方法配置,能够根据一定的条件对缓存进行清空
  • @CachePut 更新缓存(不会影响到方法的运行),这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。
  • @Caching 重新组合要应用于方法的多个缓存操作
  • @CacheConfig 设置类级别上共享的一些常见缓存设置

3.1 @Cacheable

3.1.1 通过指定的key,将查询结果缓存到redis中

@Service
public class StudentService implements IStudentService {

    @Resource
    private StudentMapper studentMapper;

    @Cacheable(value = "students",key = "#student.toString()")
    @Override
    public List<student> list(Student student) {
        return studentMapper.list(student);
    }

}
</student>

属性描述示例methodName当前方法名#root.methodNamemethod当前方法#root.method.nametarget当前被调用的对象#root.targettargetClass当前被调用的对象的class#root.targetClassargs当前方法参数组成的数组#root.args[0]caches当前被调用的方法使用的Cache#root.caches[0].name

3.1.2 配置key的生成策略

1) xml配置文件方式

编写自定义key生成器

public class CustomKeyGenerator implements KeyGenerator {

    @Override
    public Object generate(Object target, Method method, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getName());
        sb.append(method.getName());
        for (Object obj : params) {
            sb.append(obj.toString());
        }
        return sb.toString();
    }
}
    <!-- 启用注解式缓存 -->
    <cache:annotation-driven cache-manager="cacheManager" key-generator="customKeyGenerator">

    <!--自定义key生成器-->
    <bean id="customKeyGenerator" class="com.zking.mybatisdemo.config.CustomKeyGenerator">
</bean></cache:annotation-driven>

2) java配置方式

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    private static final Logger log = LoggerFactory.getLogger(CacheConfig.class);

    ......

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684;&#x8FC7;&#x671F;&#x65F6;&#x95F4;
        cacheManager.setDefaultExpiration(300);
        return cacheManager;
    }

    @Bean(name="customKeyGenerator")
    public KeyGenerator customKeyGenerator() {
        return new CustomKeyGenerator();
    }

    //&#x914D;&#x7F6E;&#x81EA;&#x5B9A;&#x4E49;key&#x751F;&#x6210;&#x5668;
    @Override
    public KeyGenerator keyGenerator() {
        return new CustomKeyGenerator();
    }

}

注意: 该类必须继承CachingConfigurerSupport类,并重写其中的keyGenerator方法。

配置默认的生成策略后,如果没有指定key,则使用默认的生成策略, 如:

    @Cacheable(value = "students")
    @Override
    public List<student> list(Student student) {
        return studentMapper.list(student);
    }
</student>

3) 除默认key生成策略外,还可以指定key,或指定生成策略,如果一下示例:

    @Cacheable(value = "students", key = "'sname:' + #student.sname")
    @Override
    public List<student> list(Student student) {
        return studentMapper.list(student);
    }

    @Override
    @Cacheable(value="student",keyGenerator = "customKeyGenerator")
    public Student load(String sid) {
        return studentMapper.load(Integer.valueOf(sid));
    }
</student>

3.1.3 condition

只对学生名称以”李”字开发的的查询执行缓存,否则不进行缓存, 代码如下:

    @Cacheable(value = "students", key = "'sname:' + #student.sname", condition = "#student.sname.equals('&#x674E;')")
    @Override
    public List<student> list(Student student) {
        return studentMapper.list(student);
    }
</student>

可以使用unless参数否决向缓存添加值。

3.2 @CacheEvict

主要针对方法配置,能够根据一定的条件对缓存进行清空

示例:

    @Override
    @Cacheable(value="student", key="#sid.toString()")
    public Student load(Integer sid) {
        return studentMapper.load(sid);
    }

    @CacheEvict(value="student", key="T(Integer).toString(#student.sid)")
    //@CacheEvict(value="student", key="#student.sid + ''")
    @Override
    public void update(Student student) {
        studentMapper.update(student);
    }

测试代码:

    @Test
    public void load() {
        Student student = studentService.load(197);
        System.out.println(student);
    }

    @Test
    public void update() {
        Student student = new Student();
        student.setSid(197);
        student.setSname("&#x66F9;&#x96EA;&#x5B66;");
        student.setAge(56);
        student.setRemark("&#x6D4B;&#x8BD5;");
        studentService.update(student);
    }

先运行load测试, 会将sid为197的学生信息缓存,然后再运行update,会将sid为197的学习信息从缓存中删除。

使用allEntries属性从缓存中退出所有条目。如下示例:

    @CacheEvict(cacheNames="books", allEntries=true)
    @Override
    public void update(Student student) {
        studentMapper.update(student);
    }

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素
示例:

@CacheEvict(value="users", beforeInvocation=true)

3.3 @CachePut

对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

示例:

    @Override
    //@Cacheable(value="student", key="#sid.toString()")
    @CachePut(value = "student", key="#sid.toString()")
    public Student load(Integer sid) {
        return studentMapper.load(sid);
    }

注意: @CachePut 与 @Cacheable 之间的差别,@CachePut不会去检查缓存中是否有值, 每次都会通过获取获取数据填充到缓存中去。

3.4 @Caching

有时,需要指定相同类型的多个注释(如@CacheEvict或@CachePut) 例如,因为不同缓存之间的条件或键表达式不同。@Caching允许在同一方法上使用多个嵌套的@Cacheable、@CachePut和@CacheEvict注释。

示例代码如下:

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") }) public Book importBooks(String deposit, Date date) {
   .....

}

3.5 @CacheConfig

缓存提供了许多的注解选项,但是有一些公用的操作,我们可以使用@CacheConfig在类上进行全局设置。

@CacheConfig(keyGenerator = "customKeyGenerator")
public class StudentService implements IStudentService {

    @Cacheable(value = "students")
    @Override
    public List<student> list(Student student) {
        return studentMapper.list(student);
    }
    ....

 }</student>

Original: https://blog.csdn.net/m0_64863860/article/details/127786793
Author: m0_64863860
Title: redis(基础 && redis缓存)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/653406/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球