Java整合Redis & 自定义RedisTemplate

6 篇文章 0 订阅
4 篇文章 0 订阅

Java整合Redis

服务端配置

首先配置Linux端:开放服务器防火墙的redis的端口

[root@localhost bin]# firewall-cmd --get-active-zones
public
  interfaces: ens33
[root@localhost bin]# firewall-cmd --zone=public --add-port 6379/tcp --permanent
success
[root@localhost bin]# firewall-cmd --reload
success
[root@localhost bin]# firewall-cmd --query-port=6379/tcp
yes

修改redis的配置文件:bind远程可以访问的地址(也就是服务器在外部网络可以访问到的地址)

1、Jedis

客户端使用

简单事务

通过jedis.multi()的返回值对象,进行事务的执行与提交等操作。

    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.37.100",6379);
        jedis.flushDB();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "fall");
        jsonObject.put("sex", "man");
        String s = jsonObject.toJSONString();       // 准备数据并转换成String格式

        Transaction multi = jedis.multi();  // 开启事务,得到返回值
        try {
            multi.set("role", s);       // 通过开启事务的返回值,在事务中进行命令执行
            int i = 1/0;                // 如果这里触发了异常,就会进入catch块
            multi.exec();               // 如果正常执行,就执行事务
        } catch (Exception e) {
            multi.discard();            // 触发异常就撤销事务
            e.printStackTrace();
        } finally {
            System.out.println("get role:"+jedis.get("role"));  // 最后get role,看看是否放入成功了
            jedis.close();              // 关闭jedis连接
        }
    }
WATCH监控

监控一个元素达到防止数据出错的目的。

    public static void testWatch(){
        Jedis jedis = new Jedis("192.168.37.100",6379);
        jedis.flushDB();
        jedis.set("age", "18");

        // 监控age元素
        jedis.watch("age");
        Transaction multi = jedis.multi();
        try {
            // 先休眠5秒,再进行自增操作
            TimeUnit.SECONDS.sleep(10);
            // 在休眠期间进行修改age,就会触发watch,导致事务的执行失败
            multi.incr("age");
            // 设置一个其他的值
            multi.set("other", "value");
            
            multi.exec();
        } catch (Exception e) {
            multi.discard();
            e.printStackTrace();
        } finally {
            System.out.println("age = " + jedis.get("age"));
            System.out.println("other = " + jedis.get("other"));
            jedis.close();
        }
    }

测试可以发现休眠期间在其他客户端对age进行192.168.37.100:6379> INCRBY age 20自增20操作,事务的执行全部都失败了,

jedis.get(“other”)返回值为null:

2、SpringBoot整合Redis

简介

在SpringBoot2.x后,SpringBoot不再使用jedis来操作Redis,而是替换成了lettuce。

Jedis:采用直连,多线程操作时是不安全的,如果想要线程安全,就需要使用Jedis Pool连接池,更像BIO模式。

Lettuce:采用netty,实例可以在多个线程中共享,线程安全,更像NIO模式。

基础配置

# 使用spring.redis作为前缀,配置redis的相关信息
spring.redis.host=192.168.37.100
spring.redis.port=6379

操作Redis

默认配置

使用默认的RedisTemplate时,只需要自动注入,在使用时,想要操作什么数据类型就是用redisTemplate.opsForXXX类型 即可。

@SpringBootTest
class SpringbootRedisApplicationTests {
	@Autowired
	RedisTemplate<Object,Object> redisTemplate;

	@Test
	public void testRedis() {
        // opsForValue操作String
		redisTemplate.opsForValue().set("name", "fall");
		System.out.println(redisTemplate.opsForValue().get("name"));
        // opsForList操作列表
		redisTemplate.opsForList().leftPush("myKey", "value1");
		redisTemplate.opsForList().leftPush("myKey", "value2");
		redisTemplate.opsForList().leftPush("myKey", "value3");

		System.out.println(redisTemplate.opsForList().leftPop("myKey"));
		System.out.println(redisTemplate.opsForList().leftPop("myKey"));
		System.out.println(redisTemplate.opsForList().leftPop("myKey"));
		// 得到连接对象
		RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
		// 可以通过连接对象进行redis操作(如清空、关闭连接等)
		connection.flushDb();
		connection.close();

	}
}

默认配置保存java对象:(转换成字符串保存,或让实体类实现序列化接口来进行保存)

/**
 * 测试保存对象
 * 通过转换成JSON格式
 */
@Test
public void saveByJSON() throws JsonProcessingException {
   // 创建一个对象
   Person person = new Person("zs",18);

   // 将对象转换成JSON格式的字符串
   String jsonPerson = new ObjectMapper().writeValueAsString(person);

   // 存入Redis
   redisTemplate.opsForValue().set("person", jsonPerson);

   // 取出
   System.out.println(redisTemplate.opsForValue().get("person"));
}


/**
 * 通过让对象实现序列化接口,
 * 直接存储对象
 */
@Test
public void saveObject() {
   // 创建一个对象
   Person person = new Person("zs",18);

   // 直接存入Redis
   redisTemplate.opsForValue().set("person", person);

   // 取出
   System.out.println(redisTemplate.opsForValue().get("person"));
}

可以发现的使是,当直接通过这种方式保存时,redis中的key其实是经过一层编码的,显示的key不是我们输入的key,想要使RedisTemplate符合我们的习惯,就可以采用自定义RedisTemplate的方式。

自定义RedisTemplate

可以看到SpringBoot自带的RedisTemplate的源码:

@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
      throws UnknownHostException {
   RedisTemplate<Object, Object> template = new RedisTemplate<>();
   template.setConnectionFactory(redisConnectionFactory);
   return template;
}

@ConditionalOnMissingBean(name = "redisTemplate")这句注解,表示只要我们向Spring容器中加入一个RedisTemplate对象,那么这个Bean就不会生效,所以我们可以通过创建一个新的Bean,来达到自定义RedisTemplate的目的。

那么自定义的RedisTemplate代码如下(一般可以当坐模板用,不需要修改):

/**
 * 配置类,注入自定义的RedisTemplate
 */
@Configuration
public class RedisConfig {

    // 自定义一个方法返回RedisTemplate
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String,Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // JSON序列化配置
        Jackson2JsonRedisSerializer jsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jsonRedisSerializer.setObjectMapper(objectMapper);

        // String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key采用String序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value采用jackson序列化方式
        template.setValueSerializer(jsonRedisSerializer);
        // hash的value采用jackson序列化方式
        template.setHashValueSerializer(jsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }
}

将该类与其中的方法加入Spring IOC容器后,自动注入时就会采用这个自定义的Template,此时存入Redis的key变成了我们自己输入的key的样式。

同样的,为了更方便地操作Redis,网上也有许多Redis的工具类,可以免除我们用Template操作Redis时一些比较麻烦的步骤(如需要先调用opsForXXX方法)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值