Redis学习之客户端(3)
本笔记是参考《尚硅谷Redis 6 入门到精通》总结,供学习查阅
1.redis的Java客户端
进入官网查看
三种客户端比较
注意:
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();
}
1.2 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
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.创建测试类
@SpringBootTest
@RunWith(SpringRunner.class)
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testString(){
redisTemplate.opsForValue().set("k1","2222");
}
}
3.通过工具查看
4.可以看到,通过redisTemplate序列化到redis服务器的,是“乱码”的,这是因为redisTemplate默认使用的是JDK的序列化工具的序列化的
5.redis有如下几种序列化器,如下:
6.创建一个配置文件
@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.再次通过工具查看,可显示正常结果
9.保存一个对象
@Test
public void testObj(){
redisTemplate.opsForValue().set("user"
, User.builder().name("张三").age(12).build());
}
10.从上面可以知道,为了在反序列化时知道对象的类型,Json序列化器会将类的class类型写入到json里面去,再存入redis里,这样会带来额外的内存开销
针对上面json这种增加额外开销,那么我们可以用stringRedisTemplate工具来实现,把必要的json信息存入redis,然后反序列化的时候,再自己自动去识别成想要的对象即可