当我们了解了redis的五大数据类型,手动去敲一敲每个数据类型对应的命令,无论是再来看jedis,还是spring-data-redis都是很轻松的,他们提供的API都是基于原生的redis命令,可读性很强
jedis操作五大数据类型#
其实关于怎么使用jedis的对应的五大数据类型的api,就不说太多了,因为可读性真的是太强了,只要了解那么底层的命令,开箱即用,忘记了,点一下,全出来了
demo:
/** * @Author: Changwu * @Date: 2019/3/28 11:45 */ public class TextAPI { public static void main(String[] args) { Jedis jedis = new Jedis("192.168.43.150", 6379); jedis.hset("user","userName","25"); jedis.hset("user","id","1"); System.out.println(jedis.hget("user","userName")); HashMap<String, String> map = new HashMap<>(); map.put("role1","admin"); map.put("role2","user"); jedis.hmset("role",map); System.out.println(jedis.hmget("role","role1")); } }
jedis的事务demo#
Transaction multi = jedis.multi(); //放弃提交事务 multi.discard(); // 提交事务 // multi.exec();
因为他对事务是部分支持,所以一般都要加上watch
RedisPool#
一般在多线程下并发访问redis,为了提高性能,会使用redis连接池(单例)
/** * 工具方法,获取jedispool的单例 * @Author: Changwu * @Date: 2019/3/28 14:10 */ public class jedisPoolUtil { private static volatile JedisPool jedisPool = null; // 私有化构造方法 private jedisPoolUtil(){} //提供工厂方法 public static JedisPool getJedisPoolInstance(){ if (jedisPool==null){ synchronized (jedisPoolUtil.class){ if (jedisPool==null){ // jedispool 的相关配置 JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxIdle(32); // 最多有这么多尅空闲 poolConfig.setMaxTotal(500); poolConfig.setMaxWaitMillis(100*1000); //最长等待的时间 poolConfig.setTestOnBorrow(true); // 获取redis连接时,是否检验redis的连接可用性 return new JedisPool(poolConfig,"192.168.43.150",6379); } } } return jedisPool; } /** * 关闭具体某个池子的某个实例 * @param jedis */ public static void release(Jedis jedis){ if (jedis!=null){ jedis.close(); } }
spring-data-redis#
spring整个redis后提供了如下两个模板,供我们去操作redis
@RunWith(SpringRunner.class) @SpringBootTest public class BootRedisApplicationTests { @Autowired RedisTemplate redisTemplate; @Autowired StringRedisTemplate stringRedisTemplate;
- 前者的kv 全是object
- 后者的kv 全是string
大多数情况下,我们都是把string字符串往redis里面存储,所以更倾向于StringRedisTemplate
两套模板针对五大数据类型对应如下api,同样可读性依然超级好
header 1 | header 2 |
操作字符串 | redisTemplate.opsForValue() |
操作hash | redisTemplate.opsForHash() |
操作list | redisTemplate.opsForList() |
操作set | redisTemplate.opsForSet() |
操作zset | redisTemplate.opsForZSet() |
注意点:
RedisTemplate 前者针对对象操作,要求我们的bean要是实现可序列化接口Serializable
- 默认会使用jdk默认的序列化机制,把序列化后的数据保存到redis,当我们直接去redis上查看存进去的对象时,看到的无异于一堆乱码(当然并没错,依旧可以通过反序列化得到对象)
如何解决?
- 我们可以先把对象手动转化成json,再存储到redis
- 定制RedisTemplate
在redis的自动配置类中我们可以看到它的自动配置
@Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration { @Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; }
跟进 RedisTemplate 可以找到他默认使用的序列化器是 jdk的
@Override public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; if (defaultSerializer == null) { defaultSerializer = new JdkSerializationRedisSerializer( classLoader != null ? classLoader : this.getClass().getClassLoader()); }
我们要做的就是定制一个自己的关于redis的配置类,让他覆盖掉自动配置
新建类,加@Configuration
注解 , 拷贝原自动配置类的代码段,替换掉 它指定序列化器的部分
@Configuration public class redisConfig { @Bean public RedisTemplate<Object, 将被序列化的类名> redisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, 将被序列化的类名> template = new RedisTemplate<Object, 将被序列化的类名>(); template.setConectionFactory(redisConnectionFactory); // 更换默认的序列化器 RedisSerializer ser= new Jackson2JsonRedisSerializer<将被序列化的类名>(将被序列化的类名.Class); template.setDefaultSerializer(ser); return template; } }
自动注入我们指定的redisTemplate
@Autowired RedisTemplate<Object,将要序列化的类名> redisTemplate;