Redis的Java客户端

3.Redisson

Redisson是一个基于Redis实现的分布式、可伸缩的Java数据结构集合。包含了诸如Map、Queue、Lock、Semaphore、AtomicLone等强大的功能。

4.Java中使用Jedis

(1):引入依赖

复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.4.1</version>
</dependency>

(2):建立连接

复制代码
//建立连接
Jedis jedis=new Jedis("127.0.0.1",6379);
//选择库
jedis.select(0);

测试代码

复制代码
Jedis jedis=new Jedis("127.0.0.1",6379);
        jedis.select(0);
        System.out.println(jedis.set("name","tom"));
        //查询name
        String name=jedis.get("name");
        System.out.println( "Hello World!" +name);
        //查询Hash类型的user:2的值
        Map<String, String> stringStringMap = jedis.hgetAll("user:2");
        System.out.println(stringStringMap);
        //更新Hash类型的field的值
        jedis.hset("user:2","age","1111");
        System.out.println("修改后:"+stringStringMap);

Jedis连接池

Jedis本身线程不安全,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用jedis连接池代替Jedis的直连方式

实现,使用静态工厂生成jedis对象

复制代码
public class JedisConnectionFactory {
    private static final JedisPool jedispool;
    static {
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        //设置最大连接数
        jedisPoolConfig.setMaxTotal(8);
        //设置最大空闲连接数
        jedisPoolConfig.setMaxIdle(8);
        //设置最小空闲连接数
        jedisPoolConfig.setMinIdle(0);
        //设置最长等待时间
        jedisPoolConfig.setMaxWaitMillis(200);
        jedispool=new JedisPool(jedisPoolConfig,"127.0.0.1",6379);

    }
    //获取jedis对象
    public static Jedis getjedis()
    {
        return jedispool.getResource();
    }
    
}
5.SpringDataRedis

SpringDataRedis是Spring中数据操作的模块,包含对各种数据的集成,其中Redis的集成模块叫做SpringDataRedis。

提供了对不同Redis客户端的整合(Lettuce和Jedis)

提供RedisTemplate统一API来操作Redis

支持Redis的发布订阅模型

支持Redis哨兵和Redis集群

支持基于Lettuce的响应式编程

支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化,就是将java对象变成字节存进去,以及读取出来。

支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种Redis的操作。并且将不同数据类型的操作API封装到不同类型中:

如何使用SpringDataRedis

在SpringBoot项目的pom文件引入:

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
</dependency>

配置applicaiton.properties文件

复制代码
server.port=8080
spring.redis.host=127.0.0.1
spring.redis.port=6379
#最大连接数
spring.redis.lettuce.pool.max-active=8
#最大空闲连接数
spring.redis.lettuce.pool.max-idle=8
#最小空闲连接数
spring.redis.lettuce.pool.min-idle=0
#连接等待时间
spring.redis.lettuce.pool.max-wait=100

但是我们图形化工具显示:

怎么会这样?其实是jdk的序列化,redisTemplate.opsForValue().set("name1","李四");接收的key是一个object对象,这就会出现问题:可读性差;内存占用大,解决这个问题就必须改变RedisTemplate的序列化方式:

在此之前先引入jackson的依赖

复制代码
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

编写配置类

复制代码
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
        //创建RedisTemplate对象
        RedisTemplate<String, Object> stringObjectRedisTemplate = new RedisTemplate<>();
        //设置连接工厂
        stringObjectRedisTemplate.setConnectionFactory(connectionFactory);
        //创建JSON序列化工厂
        GenericJackson2JsonRedisSerializer jsonRedisSerializer=new GenericJackson2JsonRedisSerializer();
        //设置key的序列化
        stringObjectRedisTemplate.setKeySerializer(RedisSerializer.string());
        stringObjectRedisTemplate.setHashKeySerializer(RedisSerializer.string());
        //设置value的序列化
        stringObjectRedisTemplate.setValueSerializer(jsonRedisSerializer);
        stringObjectRedisTemplate.setHashValueSerializer(jsonRedisSerializer);
        //返回
        return stringObjectRedisTemplate;
    }
}

@Autowired
private RedisTemplate<String ,Object> redisTemplate;
@Test
void contextLoads() {
redisTemplate.opsForValue().set("name1","李四");
    Object name=redisTemplate.opsForValue().get("name1");
    System.out.println(name);

}

这样更改配置就正常了。

复制代码
redisTemplate.opsForValue().set("user2",new User("aaa",12));
Object user2 = redisTemplate.opsForValue().get("user2");
System.out.println(user2);

甚至可以将一个对象序列化和反序列化!但仍存在问题

为了在反序列化时知到是对象类,JSON序列化器会将类的class类型写入json结果中,存入Redis,会带来额外的内存开销。为了节省空间,我们并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储java对象时,手动完成对象的序列化和反序列化。

那我们还需要重新编写RedisConfig类吗?不需要,Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String。省去了我们自定义RedisTemplate的过程:

测试代码如下:

复制代码
@Autowired
    private StringRedisTemplate stringRedisTemplate;
    //Json工具
    private static  final ObjectMapper mapper=new ObjectMapper();
    @Test
    void contextLoads() throws JsonProcessingException {
        //准备存入对象
        User user3=new User("虎哥",11);
        //手动序列化
        String json=mapper.writeValueAsString(user3);
        //写入数据
        stringRedisTemplate.opsForValue().set("user:3",json);
        //读取数据
        String s = stringRedisTemplate.opsForValue().get("user:3");
        System.out.println(s);
        //反序列化
        User user=mapper.readValue(s,User.class);
        System.out.println("user3="+user);


    }

}

综上所述:RedisTemplate有两种序列化实践方案

方案一:

1.自定义RedisTemplate

2.修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

(虽然可以自动序列化和反序列化,但是有额外的开销)

方案二:

1.使用StringRedisTemplate

2.写入Redis时,手动把对象序列化为JSON

3.读取Redis是吗,手动读取到的JSON反序列化为对象

RedisTemplate操作hash类型的数据

复制代码
 @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //Json工具
    private static  final ObjectMapper mapper=new ObjectMapper();
    @Test
    void contextLoads() throws JsonProcessingException {
        //存放数据
        stringRedisTemplate.opsForHash().put("user:2","name","李四");
        stringRedisTemplate.opsForHash().put("user:2","age","24");
        //读取field值
        Object name = stringRedisTemplate.opsForHash().get("user:2", "name");
        //读取所有field的值
        Map<Object, Object> user2 = stringRedisTemplate.opsForHash().entries("user:2");
        System.out.println(name);
        System.out.println(user2);
    }
相关推荐
不爱编程的小九九18 分钟前
小九源码-springboot097-java付费自习室管理系统
java·开发语言·spring boot
爬山算法29 分钟前
Redis(78) 如何设置Redis的缓存失效策略?
数据库·redis·缓存
独自破碎E40 分钟前
LeetCode 381: O(1) 时间插入、删除和获取随机元素 - 允许重复
java·算法·leetcode
程语有云42 分钟前
生产事故-Caffeine缓存误用之临下班的救赎
java·缓存·caffeine·阻塞·log·生产事故
Miraitowa_cheems1 小时前
LeetCode算法日记 - Day 81: 最大子数组和
java·数据结构·算法·leetcode·决策树·职场和发展·深度优先
CodeCraft Studio1 小时前
国产化Word处理控件Spire.Doc教程:用Java实现TXT文本与Word互转的完整教程
java·c#·word·spire.doc·word文档转换·txt转word·word转txt
徐子童1 小时前
数据结构---优先级队列(堆)
java·数据结构·面试题·优先级队列··topk问题
DemonAvenger1 小时前
深入Redis String:从基础到实战,10年经验的后端工程师带你解锁最佳实践
数据库·redis·性能优化
滑水滑成滑头1 小时前
**标题:发散创新:智能交通系统的深度探究与实现**摘要:本文将详细
java·人工智能·python
shuair1 小时前
redis大key问题
数据库·redis·缓存