redis详解--springboot整合redis

1. java连接redis

复制代码
思考: 我们之前操作redis都是通过命令行的客户端来操作。 在开发时都是通过java项目操作redis.

引入Redis依赖

java 复制代码
<!--引入java连接redis的驱动-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.3.1</version>
        </dependency>
1.1 连接redis

最简单的连接方式,就是通过 Jedis 对象连接。代码如下:

java 复制代码
//引入Redis驱动程序
import redis.clients.jedis.Jedis;

public class RedisJava {
    public static void main(String[] args) {
        //连接Redis服务--> 默认连接本地的redis 端口号6379.
        Jedis jedis = new Jedis("172.16.7.110",6379);
        // 如果设置 Redis 服务的密码,需要进行验证,若没有则可以省去
        // jedis.auth("123456");
    }
}

所有关于redis操作的功能都在该类中Jedis

java 复制代码
//关于key的命令
        Set<String> keys = jedis.keys("*");
        System.out.println("所有的key:"+keys);

        long del = jedis.del("k1", "k2", "k3");
        System.out.println("删除key的个数:"+del);

        boolean k4 = jedis.exists("k4");
        System.out.println("判断指定的k4是否存在:"+k4);

        long k5 = jedis.expire("k5", 10);
//关于字符串类型的命令:
        String set = jedis.set("k1", "v1");
        System.out.println("存入k1的值:"+set);

        String k1 = jedis.get("k1");
        System.out.println("获取指定key的值:"+k1);

        long k2 = jedis.setnx("k2", "110");
        System.out.println("如果k2不存在,则设置k2的值:"+k2);

        long k21 = jedis.incr("k2");
        System.out.println("k2的值加1:"+k21);

        long k22 = jedis.decr("k2");
        System.out.println("k2的值减1:"+k22);

        String setex = jedis.setex("k3", 100, "v3");
        System.out.println("k3的值:"+setex);
//关于hash类型的命令:
        long hset = jedis.hset("k4", "k41", "v41");
        System.out.println("存入k4的键值对:"+hset);
        Map<String,String> map=new HashMap<>();
        map.put("name","张三");
        map.put("age","18");
        long k51 = jedis.hset("k5", map);
        System.out.println("存入k5的键值对:"+k51);
        String hget = jedis.hget("k5", "name");
        System.out.println("获取k5的name的值:"+hget);
        Map<String, String> k52 = jedis.hgetAll("k5");
        System.out.println("获取k5的所有键值对:"+k52);
1.2 java连接redis集群模式

适合ssm项目

java 复制代码
 public static void main(String[] args) {
        Set<HostAndPort> nodes=new HashSet<>();
        nodes.add(new HostAndPort("192.168.111.188",7001));
        nodes.add(new HostAndPort("192.168.111.188",7002));
        nodes.add(new HostAndPort("192.168.111.188",7003));
        nodes.add(new HostAndPort("192.168.111.188",7004));
        nodes.add(new HostAndPort("192.168.111.188",7005));
        nodes.add(new HostAndPort("192.168.111.188",7006));
        JedisCluster jedisCluster=new JedisCluster(nodes);
        jedisCluster.set("k5","666");
        System.out.println(jedisCluster.get("k5"));
    }

2. springboot整合redis

引入依赖

复制代码
       <!--引入了redis整合springboot 的依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

修改配置文件

properties 复制代码
#配置redis信息
#redis服务器地址
spring.redis.host=localhost
#redis服务器端口
spring.redis.port=6379
#连接池最大连接数(使用负数表示没有限制)默认8
spring.redis.lettuce.pool.max-active=100
#连接池最大阻塞等待时间(使用负值表示没有限制)默认-1
spring.redis.lettuce.pool.max-wait=PT10S
#连接池最大空闲连接数(使用负值表示没有限制)默认8
spring.redis.lettuce.pool.max-idle=30
#连接池最小空闲连接数(使用负值表示没有限制)默认0
spring.redis.lettuce.pool.min-idle=1
#连接超时时间
spring.redis.timeout=PT10S

使用

springboot整合redis时封装了两个工具类:StringRedisTemplate和RedisTemplate.

StringRedisTemplate它是RedisTemplate的子类。StringRedisTemplate里面只能存放字符串的内容。

1. StringRedisTemplate
java 复制代码
@Autowired
    private StringRedisTemplate stringRedisTemplate;
//关于key的操作
    @Test
    void textkey() {
        Set<String> keys = stringRedisTemplate.keys("*");
        System.out.println("查询全部:"+keys);
        Boolean k1 = stringRedisTemplate.delete("k1");
        System.out.println("删除是否成功:"+k1);
        Boolean k2 = stringRedisTemplate.hasKey("k2");
        System.out.println("查询指定k是否存在:"+k2);
        Boolean k11 = stringRedisTemplate.expire("k1", 10, TimeUnit.SECONDS);
        System.out.println("设置过期时间的k"+k11);
    }

//关于String的操作: 在封装的StringRedisTemplate类对应每种数据类型的操作 对应相应的类来完成
    @Test
    void textString(){
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        //存放数据
        opsForValue.set("k1","k1");
        //存放并设置过期时间
        opsForValue.set("k2","20",2,TimeUnit.MICROSECONDS);
        //存放(有则不存放,无则存放)并设置过期时间
        Boolean aBoolean = opsForValue.setIfAbsent("k3", "v3", 2, TimeUnit.MICROSECONDS);
        System.out.println("是否设置成功:"+aBoolean);
        //获取指定k
        String k1 = opsForValue.get("k1");
        System.out.println("获取指定k"+k1);
        //设置增量
        Long k2 = opsForValue.increment("k2", 10);
        System.out.println("获取增量后的值:"+k2);
    }

 //关于Hash的操作
    @Test
    public void testHash(){
        HashOperations<String, Object, Object> forHash = 		               stringRedisTemplate.opsForHash();
        //存放数据  hset(key,field,value)
        forHash.put("user","name","ykq");
        Map<String,String> map=new HashMap<>();
        map.put("age","18");
        map.put("adrress","北京");
        forHash.putAll("user",map);
        //获取指定的元素  hget(key,field)
        Object o = forHash.get("user", "name");
        System.out.println("获取指定的元素:"+o);
        Map<Object, Object> user = forHash.entries("user");
        System.out.println("获取所有的元素:"+user);

        Set<Object> user1 = forHash.keys("user");
        System.out.println("获取所有的key:"+user1);
        List<Object> user2 = forHash.values("user");
        System.out.println("获取所有的value:"+user2);
    }
2. RedisTemplate
复制代码
它属于StringRedisTemplate的父类,它的泛型默认都是Object。它可以直接存储任意类型的key和value.
java 复制代码
 @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test01(){
        //指定key的序列化方式。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //指定value的序列化方式
        redisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));
		
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //发现redis的database库中出现了乱码?
        // 1.key要不要序列化。要。默认使用的是jdk序列化方式 。
        valueOperations.set("k11","v11");

        System.out.println(valueOperations.get("k11"));//能否获取值。--能

        //org.springframework.data.redis.serializer.SerializationException: 序列化
        //发现报错--序列化异常---原因-User对象没有序列化
        //把内存中的数据存入磁盘---序列化过程
        valueOperations.set("k12",new User("fwx",18));

        JSONObject k12 = (JSONObject) valueOperations.get("k12");

    }

如果使用RedisTemplate每次都需要人为指定key和value的序列化

所以可以自己配置

java 复制代码
@Configuration
public class RedisTemplateConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {

        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);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean

    public StringRedisTemplate stringRedisTemplate(
            RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}
3. 集群模式
复制代码
#集群模式
#在application配置文件中配置
spring.redis.cluster.nodes=192.168.111.188:7006,192.168.111.188:7001,192.168.111.188:7002,192.168.111.188:7003,192.168.111.188:7004,192.168.111.188:7005

3. 案例--短信业务

java 复制代码
public class SendMsgUtil {
    /**
     * 使用AK&SK初始化账号Client
     * @return Client
     * @throws Exception
     */
    
    public static Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId("aliyun的账号")

                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret("aliyun的密钥");
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.teaopenapi.Client(config);
    }

    /**
     * API 相关
     * @return OpenApi.Params
     */
    public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception {
        com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params()
                // 接口名称
                .setAction("SendSms")
                // 接口版本
                .setVersion("2017-05-25")
                // 接口协议
                .setProtocol("HTTPS")
                // 接口 HTTP 方法
                .setMethod("POST")
                .setAuthType("AK")
                .setStyle("RPC")
                // 接口 PATH
                .setPathname("/")
                // 接口请求体内容格式
                .setReqBodyType("json")
                // 接口响应体内容格式
                .setBodyType("json");
        return params;
    }

    public static String sendCode(String phone) throws Exception {
        com.aliyun.teaopenapi.Client client = createClient();
        com.aliyun.teaopenapi.models.Params params = createApiInfo();
        // query params
        java.util.Map<String, Object> queries = new java.util.HashMap<>();
        queries.put("PhoneNumbers", "13388569043");
        queries.put("SignName", "短信服务的签名");
        queries.put("TemplateCode", "短信服务的模板"); //您正在申请手机注册,验证码为:${code},5分钟内有效!
        String code="123456";
        queries.put("TemplateParam", "{\"code\":\""+code+"\"}");
        // runtime options
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest()
                .setQuery(com.aliyun.openapiutil.Client.query(queries));
        // 复制代码运行请自行打印 API 的返回值
        // 返回值为 Map 类型,可从 Map 中获得三类数据:响应体 body、响应头 headers、HTTP 返回的状态码 statusCode
        client.callApi(params, request, runtime);
        return code;
    }
}
相关推荐
Java陈序员16 小时前
企业级!一个基于 Java 开发的开源 AI 应用开发平台!
spring boot·agent·mcp
杨运交1 天前
[041][公共模块]分布式唯一ID生成器设计与实现:一款灵活可扩展的雪花算法框架
spring boot
用户3074596982072 天前
Redis 延时队列详解
redis
烤代码的吐司君2 天前
Redis 数据结构 ZSet, BIT, HyperLogLog,Geo 空间数据
redis·后端
Flittly2 天前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
Flynt3 天前
从Spring Boot 4.0升到4.1,我在Maven和gRPC上栽了跟头
java·spring boot·后端
掉鱼的猫4 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·spring boot
leeyi4 天前
Checkpoint 机制:Agent 怎么在断电后接着跑
redis·aigc·agent
人活一口气5 天前
Spring Boot与AIGC的完美结合:从零搭建智能内容生成平台
java·spring boot·aigc
云技纵横5 天前
一个 @Async 让循环依赖暴雷:Spring 代理的暗坑
redis