使用java连接redis

redis的发布订阅

什么是发布订阅

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

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

Redis的发布和订阅

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

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

发布订阅的代码实现:

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

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

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

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

 

返回1,是订阅者数量;

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

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

redis事务

事务简介

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

单独的隔离的操作

官网说明

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

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

执行事务的关键字:

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

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

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

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

例:

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

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

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

1.调用 EXEC 之前的错误

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

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

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

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

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

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,表示事务无法触发。

事务回滚:

redis的使用

java操作redis

第一步:创建java项目;

第二步:添加redis的依赖;

<!--redis依赖   jedis是redis官方推荐使用的客户端-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.2.0</version>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>RELEASE</version>
    <scope>test</scope>
 </dependency>

​

相关的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);
        }


}

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<String> 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类型

redis整合Springboot项目

第一步:创建springboot项目;

第二步:加入springboot依赖;

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


<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.6.0</version>
</dependency>


<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

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

Spring缓存注解

1.配置文件

/*redis的缓存*/
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer<String> 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;
    }

  • 15
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值