使用java连接redis

redis的发布订阅

什么是发布订阅

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。

Redis 客户端可以订阅任意数量的频道。

Redis的发布和订阅

客户端订阅频道发布的消息

使用java连接redis_第1张图片

频道发布消息 订阅者就可以收到消息

使用java连接redis_第2张图片

发布订阅的代码实现:

第一步:打开一个客户端订阅cc;

关键字:subscribe  自定义频道名字

使用java连接redis_第3张图片

第二步:客户端 ,发布信息;(在另一台虚拟机上发布信息);

关键字:publish 频道名字 发布内容

 

返回1,是订阅者数量;

第三步:打开第一个客户端可以看到另一个客户端发送的消息;

使用java连接redis_第4张图片

发布订阅模式,订阅多个频道;

redis事务

事务简介

可以一次执行多个命令,本质是一组命令的集合。一个事务中的 所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞。

单独的隔离的操作

官网说明

https://redis.io/docs/interact/transactions/

MULTI、EXEC、DISCARD、WATCH。这四个指令构成了 redis 事务处理的基础。

使用java连接redis_第5张图片

执行事务的关键字:

1.MULTI 用来组装一个事务;将命令存放到一个队列里面;

2.EXEC 用来执行一个事务;//commit

3.DISCARD 用来取消一个事务;回滚//rollback

4.WATCH 用来监视一些 key,一旦这些 key 在事务执行之前被改变,则取消事务的执行。

例:

在事务执行之前 如果监听的key的值有变化就不能执行;

使用java连接redis_第6张图片

在事务执行之前 如果监听的key的值没有变化就能执行;

使用java连接redis_第7张图片

有关事务,遇到的两种错误:

1.调用 EXEC 之前的错误

“调用 EXEC 之前的错误”,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis 都会进行记录,在客户端调用 EXEC 时,redis 会拒绝执行这一事务

使用java连接redis_第8张图片

第一种错误:Exec之前就出现错误,执行的时候所有的语句都不执行;

使用java连接redis_第9张图片

第二种错误:Exec之后出现错误,除错误的语句不执行外,其他语句正常执行;

类型不同,第一条语句是String字符串类型;而第二条语句把String字符串类型作为Set集合类型进行缓存,是不行的;

使用java连接redis_第10张图片

注:而对于“调用 EXEC 之后的错误”,redis 则采取了完全不同的策略,即 redis 不会理睬这些错误,而是继续向下执行事务中的其他命令。这是因为,对于应用层面的错误,并不是 redis 自身需要考虑和处理的问题,所以一个事务中如果某一条命令执行失败,并不会影响接下来的其他命令的执行;

使用java连接redis_第11张图片

Watch 类似mysql中的乐观锁

redis事务冲突

悲观锁:select * from biao where 1=1 for update

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,

这样别人想拿这个数据就会block直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,

比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁:update uuuu set moner-=8000 where version=1 1.1

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,

每次去拿数据的时候都认为别人不会修改,所以不会上锁,

但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

可以使用版本号等机制。乐观锁适用于多读的应用类型,

这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

watch

“WATCH”可以帮我们实现类似于“乐观锁”的效果,即 CAS(check and set)。

WATCH 本身的作用是“监视 key 是否被改动过”,而且支持同时监视多个 key,只要还没真正触发事务,WATCH 都会尽职尽责的监视,一旦发现某个 key 被修改了,在执行 EXEC 时就会返回 nil,表示事务无法触发。

使用java连接redis_第12张图片

事务回滚:

使用java连接redis_第13张图片

redis的使用

java操作redis

第一步:创建java项目;

第二步:添加redis的依赖;



    redis.clients
    jedis
    3.2.0


    org.junit.jupiter
    junit-jupiter
    RELEASE
    test
 

相关的API

第三步:测试java是否可以连接到redis;

添加单个值,并获取;ping成功返回PONG;

redis设置的有密码的,连接是加上密码;

package com.aaa;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


public class MyTest {
    JedisPool pool = null;
    @BeforeEach
    public void aa(){
        //使用连接池连接redis数据库
        pool = new JedisPool("192.168.146.8",6379);
    }
    @Test
    public void cc(){
        try (Jedis jedis = pool.getResource()) {
            jedis.auth("zhk");
            jedis.set("k1", "8899");
            String k1 = jedis.get("k1");
            System.out.println("k1的值为:" + k1);
            String ping = jedis.ping();
            System.out.println("测试是否同" + ping);
        }


}

使用java连接redis_第14张图片

package com.aaa;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Set;


public class MyTest {
    JedisPool pool = null;
    @BeforeEach
    public void aa(){
        //使用连接池连接redis数据库
        pool = new JedisPool("192.168.146.8",6379);
    }
    @Test
    public void cc(){
        try (Jedis jedis = pool.getResource()) {
            jedis.auth("zhk");
            jedis.set("k1", "8899");
            String k1 = jedis.get("k1");
            System.out.println("k1的值为:" + k1);
            jedis.setex("age",30,"80");
            //设置选择数据库
            jedis.select(2);
            //设置键值对
            jedis.set("name","100");
            jedis.set("name1","200");
            //获取所以的key值
            Set keys = jedis.keys("*");
            System.out.println(keys.size());
            for (String key:keys) {
                System.out.println(key);
            }
            //判断key是否存在
            System.out.println(jedis.exists("name"));
            //判断key的过期时间
            System.out.println(jedis.ttl("age"));
            //获取key对应的值
            System.out.println(jedis.get("name1"));
            String ping = jedis.ping();
            System.out.println("测试是否同" + ping);
        }









    /*public static void main(String[] args) {
        //使用连接池快速连接数据库
        JedisPool pool = new JedisPool("192.168.146.8",6379);
        try (Jedis jedis = pool.getResource()) {
            jedis.auth("zhk");
            jedis.set("k1","8899");
            String k1 = jedis.get("k1");
            System.out.println("k1的值为:"+k1);
            String ping = jedis.ping();
            System.out.println("测试是否同"+ping);

        }*/







       /* //设置连接的服务器 端口号默认是6379
        // 服务器的默认值是localhost
        Jedis jedis = new Jedis("192.168.146.8",6379);
        //redis连接密码
        jedis.auth("zhk");
        jedis.set("k1","8899");
        String k1 = jedis.get("k1");
        System.out.println("k1的值为:"+"k1");
        //通过ip地址是否可以ping成功,成功返回PONG
        String s = jedis.ping();
        System.out.println(s);*/
    }
}

String类型

使用java连接redis_第15张图片

redis整合Springboot项目

第一步:创建springboot项目;

第二步:加入springboot依赖;


    org.springframework.boot
    spring-boot-starter-data-redis




    org.apache.commons
    commons-pool2
    2.6.0




    redis.clients
    jedis

t添加配置文件和配置yml文件

使用java连接redis_第16张图片

Spring缓存注解

1.配置文件

/*redis的缓存*/
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }

你可能感兴趣的:(java,redis,开发语言)