SpringBoot-redis

Jedis

我们要使用Java来操作Redis

Jedis是Redis官方推荐的java连接开发工具!使用Java操作Redis中间件

如果你要使用Java操作Redis,那么一定要对jedis十分熟悉

创建一个maven项目

导入依赖

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.3.0</version>
</dependency>

导入fastjson用作数据处理

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.74</version>
</dependency>

编码测试

  • 连接数据库
  • 操作命令
  • 断开连接
package com.company;


import redis.clients.jedis.Jedis;

public class TestPing {
    public static void main(String[] args) {
        //1. new Jedis对象即可

        Jedis  jedis= new Jedis("127.0.0.1",6379);

        //Jedis 所有的命令就是我们之前学习的所有指令!
        //指令学习很重要
        System.out.println(jedis.ping());

    }
}

输出:PONG

常用的API

String

List

Set

Hash

Zet

测试

package com.company;

import redis.clients.jedis.Jedis;

import java.util.Set;

public class TestKey {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1",6379);
        System.out.println("清空数据“"+jedis.flushDB());
        System.out.println("判断某个键是否存在:"+jedis.exists("username"));
        System.out.println("新增<'username','ming'>的键值对:"+jedis.set("username","ming"));
        System.out.println("新增<'password','password'>的键值对:"+jedis.set("password","password"));
        System.out.println("系统中所有的键如下:");
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);
        System.out.println("删除键password:"+jedis.del("password"));
        System.out.println("判断键password是否存在:"+jedis.exists("password"));
        System.out.println("查看键username所存储的值的类型:"+jedis.type("username"));
        System.out.println("随机返回key空间的一个:"+jedis.randomKey());
        System.out.println("重命名key:"+jedis.rename("username","name"));
        System.out.println("取出改后的name:"+jedis.get("name"));
        System.out.println("按索引查询:"+jedis.select(0));
        System.out.println("删除当前数据库中的所有key:"+jedis.flushDB());
        System.out.println("返回当前数据库中key的数目:"+jedis.dbSize());
        System.out.println("删除所有数据库中的所有key:"+jedis.flushAll());
    }
}
package com.company;

import redis.clients.jedis.Jedis;

import java.util.concurrent.TimeUnit;

public class TestString {

    public static void main(String[] args) throws InterruptedException {
        Jedis jedis = new Jedis("127.0.0.1",6379);
        jedis.flushDB();
        System.out.println("=============增加数据===============");

        System.out.println(jedis.set("key1","value1"));
        System.out.println(jedis.set("key2","value2"));
        System.out.println(jedis.set("key3","value3"));
        System.out.println("删除键key2:"+jedis.del("key2"));
        System.out.println("获取键key2:"+jedis.get("key2"));
        System.out.println("修改键key1:"+jedis.set("key1","value1Changed"));
        System.out.println("获取键key1的值:"+jedis.get("key1"));
        System.out.println("在key3后面加入值:"+jedis.append("key3","end"));
        System.out.println("key3的值:"+jedis.get("key3"));
        System.out.println("增加多个键值对:"+jedis.mset("key01","value01","key02","value02","key03","value03"));
        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03","key04"));
        System.out.println("删除多个键值对:"+jedis.del("key01","key02"));
        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
        jedis.flushDB();
        System.out.println("==========新增键值对防止覆盖原先值=========================");
        System.out.println(jedis.setnx("key1","value1"));
        System.out.println(jedis.setnx("key2","value2"));
        System.out.println(jedis.setnx("key2","value2-new"));
        System.out.println(jedis.get("key1"));
        System.out.println(jedis.get("key2"));

        System.out.println("==========新增键值对并设置有效期=========================");
        System.out.println(jedis.setex("key3",2,"value3"));
        System.out.println(jedis.get("key3"));
        TimeUnit.SECONDS.sleep(3);
        System.out.println(jedis.get("key3"));


        System.out.println("==========获取原值,更新为新值=========================");
        System.out.println(jedis.getSet("key2","key2GetSet"));
        System.out.println(jedis.get("key2"));
        System.out.println("获得key2的值的字符串"+jedis.getrange("key2",2,4));
    }
}

所有的API命令就是redis命令

通过Jedis再次理解事务

package com.company;

import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TestTX {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1",6379);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("hello","world");
        jsonObject.put("name","ming");
        //开启事务
        Transaction multi = jedis.multi();
        String s = jsonObject.toString();
        try{
            multi.set("user1",s);
            multi.set("user2",s);

            multi.exec();//执行事务
        }catch (Exception e){
            multi.discard();
            e.printStackTrace();
        }finally {
            System.out.println(jedis.get("user1"));
            System.out.println(jedis.get("user2"));
            jedis.close();//关闭连接
        }



    }
}

SpringBoot集成Redis

SpringBoot操作数据: spring-data jpa mongodb redis

spring-data 是和springboot 齐名的项目

新建springboot项目

勾选Developer Tools,web->spring web,NoSql -springdata-redis

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

说明:在SpringBoot2.x之后,原来使用的jedis替换为了lettuce

jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池 更像BIO模式

lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程数据 更像NIO模式

RedisTemplate

导入依赖

配置连接

# SpringBoot所有的配置类,都有一个自动配置类  RedisAutoConfiguration
# 自动配置类都会绑定一个properties 配置文件  RedisProperties

#配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

测试

package com.company;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
class SpringbootRedisApplicationTests {

    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void contextLoads() {

        //操作不同的数据类型,api和指令是一样的
        //opsForValue 操作字符串  类似String
        //opsForList  操作list



        /*//获取连接
        RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
        connection.flushAll();
        connection.flushDb();*/


        redisTemplate.opsForValue().set("mykey","ming");
        System.out.println(redisTemplate.opsForValue().get("mykey"));
    }

}

自定义RedisTemplate

直接传对象,会报错,需要序列化

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private String name;
    private int age;

}
    @Test
    void test() throws JsonProcessingException {
        //真实的开发一般都使用json来传递对象
        User user = new User("小明", 3);
       // String s = new ObjectMapper().writeValueAsString(user);
        redisTemplate.opsForValue().set("user",user);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }

所有的对象需要序列化

package com.company.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private String name;
    private int age;

}

序列化后可以通过,默认jdk序列化方式

package com.company.config;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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 {

    //固定模板
    //自定义RedisTemplate

    //编写我们自己的redisTemplate

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        
        //我们为了自己开发方便,一般直接使用<String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate();

        template.setConnectionFactory(factory);
        
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);

        ObjectMapper om = new ObjectMapper();
        
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        
        //配置具体的序列化方式
        
        //key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        
        //hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        
        //value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);


        //hash的value采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}

自定义RedisUtils

package com.company.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.TimeUnit;

public class RedisUtils {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 指定缓存失效时间
     * @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  可以传一个值,或者多个
     */
    public void del(String key){
        if(key!=null&& key.length()>0){
            redisTemplate.delete(key);
        }else{
            redisTemplate.delete(CollectionUtils.arrayToList(key));
        }
    }
}
posted @ 2020-11-09 17:38  yourText  阅读(117)  评论(0编辑  收藏  举报