Redis学习之客户端(3)

71 阅读3分钟

Redis学习之客户端(3)

本笔记是参考《尚硅谷Redis 6 入门到精通》总结,供学习查阅

1.redis的Java客户端

进入官网查看

image-20220731163330968

三种客户端比较

image-20220731163700916

注意:

1.Jedis中的Java方法基本和Redis的API保持着一致,了解Redis的API,也就能熟练的使用Jedis

2.Jedis 3.5.2支持 jdk7, 从3.6.0 开始,需要jdk8

3.Jedis 的连接实例是线程不安全的,于是需要维护一个连接池,每个线程需要时从连接池取出连接实例,完成操作后或者遇到异常归还实例。当连接数随着业务不断上升时,对物理连接的消耗也会成为性能和稳定性的潜在风险点。

4.Lettuce 使用 Netty 作为通信层组件,其连接实例是线程安全的,并且在条件具备时可访问操作系统原生调用 epoll, kqueue 等获得性能提升

1.1 Jedis

1.可以参考github上,引入pom

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

2.编写代码

    private Jedis jedis;

    @Before
    public void start(){
        jedis = new Jedis("192.168.44.135",6379);
        jedis.auth("123456");
        jedis.select(0);
        jedis.flushDB();
    }

    @Test
    public void testJedis(){

        /**
         * 测试 通用命令
         */
        jedis.set("k1", "v1");
        jedis.set("k2", "v2");
        jedis.set("k3", "v3");
        Set<String> keys = jedis.keys("*");
        System.out.println(keys.size());
        for (String key : keys) {
            System.out.println(key);
        }
        System.out.println(jedis.exists("k1"));
        System.out.println(jedis.ttl("k1"));
        System.out.println(jedis.get("k1"));

        /**
         * 测试 string
         */
        jedis.mset("str1","v1","str2","v2","str3","v3");
        System.out.println(jedis.mget("str1","str2","str3"));

        /**
         * 测试 list
         */
        List<String> list = jedis.lrange("mylist",0,-1);
        for (String element : list) {
            System.out.println(element);
        }

        /**
         * 测试 set
         */
        jedis.sadd("orders", "order01");
        jedis.sadd("orders", "order02");
        jedis.sadd("orders", "order03");
        jedis.sadd("orders", "order04");
        Set<String> smembers = jedis.smembers("orders");
        for (String order : smembers) {
            System.out.println(order);
        }
        jedis.srem("orders", "order02");

        /**
         * 测试 hash
         */
        jedis.hset("hash1","userName","lisi");
        System.out.println(jedis.hget("hash1","userName"));
        Map<String,String> map = new HashMap<String,String>();
        map.put("telphone","13810169999");
        map.put("address","china");
        map.put("email","erch@163.com");
        jedis.hmset("hash2",map);
        List<String> result = jedis.hmget("hash2", "telphone","email");
        for (String element : result) {
            System.out.println(element);
        }

        /**
         * 测试 zset
         */
        jedis.zadd("zset01", 100d, "z3");
        jedis.zadd("zset01", 90d, "l4");
        jedis.zadd("zset01", 80d, "w5");
        jedis.zadd("zset01", 70d, "z6");

        List<String> zrange = jedis.zrange("zset01", 0, -1);
        for (String e : zrange) {
            System.out.println(e);
        }

    }

    @After
    public void close(){
        jedis.close();
    }

image-20220731173016402

1.2 lettuce

官网下载

Redis高级客户端Lettuce详解

1.引入pom

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>

2.代码

    private  StatefulRedisConnection<String, String> connection;
    private  RedisClient client;
    private RedisCommands<String, String> syncCommands;

    @Before
    public void start(){
        RedisURI redisUri = RedisURI.builder()
                .withHost("192.168.44.135")
                .withPort(6379)
                .withTimeout(Duration.of(10, ChronoUnit.SECONDS))
                .build();
        client = RedisClient.create(redisUri);
        connection = client.connect();
        syncCommands = connection.sync();
        syncCommands.auth("123456");
        syncCommands.flushdb();
    }

    @Test
    public void testJedis(){

        /**
         * 测试 通用命令
         */
        String pong = syncCommands.ping();
        System.out.println("pong = " + pong);

        syncCommands.set("key", "Hello, Redis!");

        HashMap<String, String> map = new HashMap<>();
        map.put("k1","v1");
        map.put("k2","v2");
        syncCommands.mset(map);
        System.out.println(syncCommands.mget("k1", "k2"));

    }

    @After
    public void close(){
        connection.close();
        client.shutdown();
    }

1.3 SpringDataRedis

官网下载

image-20220731192615407

image-20220731192711225

image-20220731192759976

1.引入相关依赖

        <!--用于测试使用-->
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

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

        <!-- spring2.X集成redis所需common-pool2-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

2.创建测试类

image-20220731195517478

@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testString(){
        redisTemplate.opsForValue().set("k1","2222");
    }
}

3.通过工具查看

image-20220731195604903

4.可以看到,通过redisTemplate序列化到redis服务器的,是“乱码”的,这是因为redisTemplate默认使用的是JDK的序列化工具的序列化的

image-20220731200035516

image-20220731200239935

5.redis有如下几种序列化器,如下:

image-20220731200329619

6.创建一个配置文件

image-20220731201018361

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //创建工具对象
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        //设置连接工厂
        template.setConnectionFactory(factory);
        //key value序列化方式
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        //hash序列化
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        return template;

    }

}

7.重新执行发送

    @Test
    public void testString(){
        redisTemplate.opsForValue().set("k2","bb1111");
    }

8.再次通过工具查看,可显示正常结果

image-20220731201129255

9.保存一个对象

    @Test
    public void testObj(){
        redisTemplate.opsForValue().set("user"
                , User.builder().name("张三").age(12).build());
    }

image-20220731214008991

10.从上面可以知道,为了在反序列化时知道对象的类型,Json序列化器会将类的class类型写入到json里面去,再存入redis里,这样会带来额外的内存开销

针对上面json这种增加额外开销,那么我们可以用stringRedisTemplate工具来实现,把必要的json信息存入redis,然后反序列化的时候,再自己自动去识别成想要的对象即可

image-20220731214435341

image-20220731214531518