🐇小怜怜的简介:

💖博客主页:浣熊小怜怜

🚀年龄:21 大二在读

💪爱好:干饭,运动,码代码,看书,音乐

🎉欢迎关注🔍点赞👍收藏🎇留言📙

🎄有任何疑问,欢迎留言讨论!!!

目录

🎈构建Spring项目

🎈SpringBoot 整合Redis

☑️ 添加依赖(pom.xml)

🎈Spring配置文件(application.properties)

🎈Jedis的测试及使用

🎈SpringBoot中使用RedisTemplate

☑️ 添加依赖(pom.xml)

🎈序列化操作

🎈构建Spring项目

文件--->新建--->项目---->Spring Initializr

💭创建时勾选NoSQL中的spring集成redis :Spring-data-redis 💭

❗❓Spring-data-redis是啥❗❓

Spring-data-redis是Spring大家族的一部分,提供了在srping应用中通过简单的连接池配置访问redis服务,对Reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装。其中的RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅,并对spring 3.1 cache进行了实现。而且RedisTemplate还支持对象缓存操作。

🎈SpringBoot 整合Redis

☑️ 添加依赖(pom.xml)

Maven Repository: Search/Browse/Explore (mvnrepository.com)

☝️ ☝️ ☝️

⏩ 到网站寻找依赖

➡️ jedis ➡️ fastjson ➡️junit

⏩ 也可以直接复制我的代码哦 ~

⬇️⬇️⬇️

            <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>3.8.0</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.76</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>

🎈Spring配置文件(application.properties)

# 应用名称
spring.application.name=RedisTemplateTest
#Redis服务器IP地址
spring.redis.host=127.0.0.1
#Redis服务器端口号
spring.redis.port=6379

🎈Jedis的测试及使用

package com.ccit.redis;
​
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import redis.clients.jedis.Jedis;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
import java.util.Iterator;
import java.util.List;
​
@RunWith(SpringRunner.class)
@SpringBootTest
public class JedisTest {
    @Value("${spring.redis.host}")
    private String redis_host;
​
    @Value("${spring.redis.port}")
    private int redis_port;
    private Jedis jedis = null;
​
    @Before
    public void testRun() {
        try {
            jedis = new Jedis(redis_host, redis_port);
            System.out.println("连接成功");
            System.out.println("服务器正在运行" + jedis.ping());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getClass() + ":" + e.getMessage());
        }
    }
​
    @Test
    public void testString() {
        try {
            jedis.set("s1", "hello world");
            System.out.println("s1:" + jedis.get("s1"));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getClass() + ":" + e.getMessage());
        }
    }
​
    @Test
    public void testList() {
        try {
            jedis.lpush("books", "Java");
            jedis.lpush("books", "Web");
            jedis.rpush("books", "NoSQL");
            System.out.println(jedis.lrange("books", 0, -1));
            List<String> list = jedis.lrange("books", 0, -1);
            Iterator<String> itList = list.iterator();
            while (itList.hasNext()) {
                System.out.println(itList.next());
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getClass() + ":" + e.getMessage());
        }
​
    }
​
    @Test
    public void testHash() {
​
    }
​
    @Test
    public void testSet() {
​
    }
​
    @Test
    public void testZset() {
​
    }
}
​

🎈SpringBoot中使用RedisTemplate

⭐ 第一部分我们对Jedis的使用进行了介绍,而且封装了一个JedisPoolUtil工具类。可是这样还是很麻烦,难道每次我们使用的时候都得复制这个JedisUtill 连接池配置工具类到新项目中?而且Jedis还不支持缓存对象的操作。程序员从来不需要重复遭轮子,Spring框架已经帮我们封装好了这一切!

☑️ 添加依赖(pom.xml)

Maven Repository: Search/Browse/Explore (mvnrepository.com)

☝️ ☝️ ☝️

⏩ 到网站寻找依赖

➡️ jackson-databind

⏩ 也可以直接复制我的代码哦 ~

⬇️⬇️⬇️

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.13.0</version>
        </dependency>

⭐ Spring框架中的spring-data-redis模块对Jedis API的进行了高度封装,提供了在Spring应用中通过简单的连接池信息配置就可以访问Redis服务并进行相关缓存操作。SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端如多线程安全的Lettuce,比Jedis多了自动管理连接池的特性,不需要我们自己的JediPoolUtil封装工具类。

⭐它还默认提供了两个使用Redis的类StringRedisTemplate和RedisTemplate,其中RedisTemplate可以支持Redis没有的缓存对象的操作,而StringRedisTemplate用来存储字符串。(其实它们都是RedisTemplate<K, V>泛型接口的实现类,我们可以自定义模板然后@AutoWired注入IOC容器中使用)

package com.ccit.redis;
​
import com.alibaba.fastjson.JSON;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
​
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateTest {
​
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
​
    @Before
    public void init() {
        try {
            System.out.println("初始化" + redisTemplate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    @Test
    public void testString() {
        try {
            //设置值
            redisTemplate.opsForValue().set("s1", "hello world");
            //获取值
            System.out.println("s1:" + redisTemplate.opsForValue());
            //设置值的同时设置超时时间
            redisTemplate.opsForValue().set("s2", "ccit", 10, TimeUnit.SECONDS);
            System.out.println("s2:" + redisTemplate.opsForValue().get("s2"));
            //设置长度
            int size = redisTemplate.opsForValue().size("s1").intValue();
            System.out.println("s1 size:" + size);
            //求子字符串
            String subString = redisTemplate.opsForValue().get("s1", 0, 5);
            System.out.println("s1 subString:" + subString);
            //删除
            boolean isDelete = redisTemplate.delete("s1");
            System.out.println("isDelete:" + ((isDelete) ? "yes" : "no"));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getClass() + ":" + e.getMessage());
        }
    }
​
    @Test
    public void testList() {
        ListOperations<String, String> listOp = redisTemplate.opsForList();
        listOp.leftPush("namelist", "mike"); // List 列表左侧插入一个元素
        listOp.leftPush("namelist", "kim");
        listOp.rightPush("namelist", "jimmy");  //往 List 列表右侧插入一个元素
        listOp.rightPush("namelist", "chuck");
        Long size = listOp.size("namelist"); //计算List列表大小
        List namelist1 = listOp.range("namelist", 0, size); //遍历整个List列表
        System.out.println("namelist1:" + JSON.toJSONString(namelist1));
​
        List namelist = listOp.range("namelist", 0, -1); //遍历整个List列表,-1表示倒数第一个即最后一个
        System.out.println("namelist:" + JSON.toJSONString(namelist));
​
        Object name1 = listOp.leftPop("namelist", 200, TimeUnit.MILLISECONDS); //从 List 列表左侧取出第一个元素,并移除
        System.out.println("is kim:" + name1.equals("kim"));
​
        Object name2 = listOp.rightPop("namelist"); //从 List 右侧列表取出第一个元素,并移除
        System.out.println("is chuck:" + name2.equals("chuck"));
    }
​
    @Test
    public void testHash() {
        try {
            HashOperations<String,String,String> hashOp = redisTemplate.opsForHash();
            hashOp.put("score", "Mike", "10"); //Hash 中新增元素。
            hashOp.put("score", "Jimmy", "9");
            hashOp.put("score", "Kim", "8");
            Assert.isTrue(hashOp.hasKey("score", "Kim")); //判断指定 key 对应的 Hash 中是否存在指定的 map 键
            String kim = hashOp.get("score", "Kim"); //获取指定 key 对应的 Hash 中指定键的值
            Set<String> name = hashOp.keys("score"); //获取hash表所有的key集合
            System.out.println(JSON.toJSONString(name));
            List<String> score = hashOp.values("score"); //获取hash表所有的values集合
            System.out.println(JSON.toJSONString(score));
            Map<String, String> map = hashOp.entries("score"); //获取"score"对应的hash表Map
            System.out.println(JSON.toJSONString(map));
            hashOp.delete("score", "Mike"); //删除指定 key 对应 Hash 中指定键的键值对
            //如果要删除整个hash表,要用redisTemplate.delete("score")方法,否则报错:Fields must not be empty
            //hashOp.delete("score");
            redisTemplate.delete("score"); //删除整个hash表
            Map<String, String> map1 = hashOp.entries("score");
​
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testSet(){
        try {
            SetOperations<String,String>setOp=redisTemplate.opsForSet();
            //向集合中添加元素,set元素具有唯一性
            setOp.add("city", "changzhou", "beijing", "shanghai", "hongkong", "hongkong");
            Long size = setOp.size("city");
            System.out.println("city size:" + size);
            //获取集合中的元素
            Set city = setOp.members("city");
            System.out.println(JSON.toJSONString(city));
            //移除集合中的元素,可以一个或多个
            setOp.remove("city", "paris");
            //判断是否是集合中的元素
            Boolean isMember = setOp.isMember("city", "hongkong");
            System.out.println("hongkong is in city:" + isMember);
            //移除并返回集合中的一个随机元素
            String city1 = setOp.pop("city");
            System.out.println(city1);
​
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    @Test
    public void testZset(){
        try {
            ZSetOperations zSetOp=redisTemplate.opsForZSet();
            //添加元素
            zSetOp.add("zcity", "beijing", 100);
            zSetOp.add("zcity", "shanghai", 95);
            zSetOp.add("zcity", "guangzhou", 75);
            zSetOp.add("zcity", "shenzhen", 85);
​
            //获取变量指定区间的元素。0, -1表示全部
            Set<String> zcity = zSetOp.range("zcity", 0, -1);
            System.out.println(JSON.toJSONString(zcity));
​
            //通过分数返回有序集合指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列
            Set<String> byScore = zSetOp.rangeByScore("zcity", 85, 100);
            System.out.println(JSON.toJSONString(byScore));
​
            //获取有序集合的成员数
            Long aLong = zSetOp.zCard("zcity");
            System.out.println("zcity size: " + aLong);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

SpringBoot 2.0已经使用Lettuce代替Jedis

🔮 其实,随着Spring Boot2.x的到来,支持的组件越来越丰富,也越来越成熟,其中对Redis的支持不仅仅是丰富了它的API,更是替换掉底层Jedis的依赖,取而代之换成了Lettuce高级Redis客户端,用于多线程安全同步,异步和响应使用。

🔮 Lettuce和Jedis的都是连接Redis Server的客户端程序。Jedis在实现上是直连redis server,多线程环境下非线程安全,除非使用连接池JedisPool,为每个Jedis实例增加物理连接。Lettuce基于Netty的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问,同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。

🔮 为了多线程安全,以前是Jedis+JedisPool组合 ,现在在SpringBoot 2.0应用中直接使用Lettuce客户端的API封装RedisTemplate即可,只要配置好连接池属性,那么SpringBoot就能自动管理连接池。

🎈序列化操作

❗❓序列化是啥❗❓

Java序列化就是指把Java对象转换为字节序列的过程

Java反序列化就是指把字节序列恢复为Java对象的过程。

⬇️⬇️⬇️ 序列化和反序列化详解看下方链接

序列化和反序列化的详解_tree_ifconfig的博客-CSDN博客_序列化和反序列化

⭐当我们的数据存储到 Redis 的时候,我们的键(key)和值(value)都是通过 Spring 提供的 Serializer 序列化到数据库的。

RedisTemplate 默认使用的是 JdkSerializationRedisSerializer,StringRedisTemplate 默认使用的是 StringRedisSerializer。

✅ 创建Java对象~

package com.ccit.redis.module;
​
public class Student {
    private int id;
    private String no;
    private String name;
​
    public Student() {
    }
​
    public Student(int id, String no, String name) {
        this.id = id;
        this.no = no;
        this.name = name;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getNo() {
        return no;
    }
​
    public void setNo(String no) {
        this.no = no;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", no='" + no + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

✅序列化操作~

package com.ccit.redis;
​
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.test.context.junit4.SpringRunner;
​
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTemplateSerialize {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired(required = false)
    private ObjectMapper objectMapper;
​
    //定义日志
    private Logger log = LoggerFactory.getLogger(RedisTemplateSerialize.class);
​
    @Before
    public void init() {
        try {
            System.out.println("初始化:" + redisTemplate);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    @Test
    public void testString() {
        String content="hello,world!";
        String key="redis:template:string";
​
        //Redis通用的操作组件
        ValueOperations valueOperations=redisTemplate.opsForValue();
​
        //将字符串信息写入缓存
        log.info("写入缓存中的内容: {} ",content);
        valueOperations.set(key,content);
​
        //从缓存中读取内容
        Object result=valueOperations.get(key);
        log.info("读取出来的内容:{} ",result);
​
    }
​
    @Test
    public void testList() {
​
    }
}

 ✔️ 项目具体的结构看下方图片~

🎉写在最后

人之所以能,是相信能。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐