- jedis
@Test
public void testString(){
//Jedis jedis = new Jedis();//表示使用的是本地的redis ,port 默认6379
Jedis jedis = new Jedis("localhost",6379);
jedis.set("uname","lisit");
System.out.println(jedis.get("uname"));
jedis.close();
}
@Test
public void testHash(){
//Jedis jedis = new Jedis();//表示使用的是本地的redis ,port 默认6379
Jedis jedis = new Jedis("localhost",6379);
jedis.hset("deptinfo","dname","Ceshi");
jedis.hset("deptinfo","did",1+"");
String key = jedis.hget("deptinfo","dname");
System.out.println(key);
Map<String ,String > map = jedis.hgetAll("deptinfo");
Set<String> keys = map.keySet();
/*for(String item : keys){
String value = map.get(item);
System.out.println(item +":" +value);
}*/
/*Iterator<String> it = keys.iterator();
while(it.hasNext()){
String key1 = it.next();
String value = map.get(key1);
System.out.println(key1+":"+value);
}*/
Set<Map.Entry<String,String>> entries = map.entrySet();
for ( Map.Entry<String,String> item: entries ) {
System.out.println(item.getKey()+":"+item.getValue());
}
jedis.close();
}
@Test
public void testlist(){
Jedis jedis = new Jedis();
jedis.del("mylist");
jedis.lpush("mylist","a" ,"b","c"); // c b a a b c
jedis.rpush("mylist","a","b","c");
List<String> list = jedis.lrange("mylist",0 , -1);
System.out.println("list.."+list);
String vallue = jedis.lpop("mylist"); // 弹出左边的c
String rvalue = jedis.rpop("mylist");// 弹出右边的c
List<String> list1 = jedis.lrange("mylist",0 , -1);
System.out.println("list1.."+list1);
}
@Test
public void testSet(){
Jedis jedis = new Jedis();
jedis.sadd("mysets","java","spring","springmvc","mybatis");
Set<String> set = jedis.smembers("mysets");
System.out.println(set);
jedis.close();
}
@Test
public void testSortedSet(){
Jedis jedis = new Jedis();
jedis.zadd("sset",12,"lisi");
jedis.zadd("sset",18,"王五");
jedis.zadd("sset",10,"赵六");
Set<String> set = jedis.zrange("sset",0,-1);
System.out.println(set);
}
@Test
public void testPool(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(50);//最大连接数
jedisPoolConfig.setMaxIdle(10);// 设置空闲连接
//获取连接池
JedisPool pool = new JedisPool(jedisPoolConfig,"localohost",6379);
Jedis jedis = pool.getResource(); // 通过连接池获取jedis
//...同上面的 ,
// 归还
jedis.close();
}
@Test
public void testJedisUtil(){
Jedis je = JedisUtils.getJedis();
Set<String> set = je.smembers("mysets");
System.out.println(set);
}
redis.properties
redis.ip=localhost
redis.port=6379
redis.maxTotal=50
redis.maxIdle=10
public class JedisUtils {
static JedisPool pool ;
static{
//读取配置文件
InputStream in = JedisUtils.class.getClassLoader().getResourceAsStream("redis.properties");
//Property 类
Properties property = new Properties();
try {
property.load(in);
} catch (IOException e) {
e.printStackTrace();
}
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(Integer.parseInt(property.getProperty("redis.maxTotal")));//最大连接数
jedisPoolConfig.setMaxIdle(Integer.parseInt(property.getProperty("redis.maxIdle")));// 设置空闲连接
pool = new JedisPool(jedisPoolConfig,property.getProperty("redis.ip"),Integer.parseInt(property.getProperty("redis.port")));
}
public static Jedis getJedis(){
return pool.getResource(); // 通过连接池获取jedis
}
}
- springboot+redis
2.1 需要实体类 implements Serializable
2.2 service 类写相关的代码
@Service
public class DeptService {
@Autowired
private DeptMapper deptMapper;
@Autowired
private RedisTemplate redisTemplate;
public List<DeptEntity> selectAllDeptService(){
List<DeptEntity> list1 = new ArrayList<>();
List<DeptEntity> list = redisTemplate.opsForList().range("dept",0,-1);
if (list.size()!= 0){
list1.addAll(list);
System.out.println("缓存.....");
}else{
list1 = deptMapper.allDept();
redisTemplate.opsForList().leftPushAll("dept",list1);
System.out.println("mysql......");
}
return list1 ;
}
}
2.3 结果
- springboot+redis 二进制存储解决方案
3.1 该方式不需要让实体类做序列化操作
3.2 新增一个配置类:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> myRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置key 和value 的序列化方式
redisTemplate.setValueSerializer(RedisSerializer.json());
redisTemplate.setKeySerializer(RedisSerializer.string());
return redisTemplate;
}
}
3.3service代码:写的时候注意注入的类名是myRedisTemplate
,不能随便乱写,这样写了才可以使用配置后的类
@Autowired
private RedisTemplate myRedisTemplate;
public List<DeptEntity> selectAllDeptService(){
List<DeptEntity> list1 = new ArrayList<>();
List<DeptEntity> list = myRedisTemplate.opsForList().range("dept",0,-1);
if (list.size()!= 0){
list1.addAll(list);
System.out.println("缓存.....");
}else{
list1 = deptMapper.allDept();
myRedisTemplate.opsForList().leftPushAll("dept",list1);
System.out.println("mysql......");
}
return list1 ;
}
使用2 也能实现效果,是因为直接序列化了,
KEY 前面带着奇怪的 16 进制字符 , VALUE 也是一串奇怪的 16 进制字符 。。。。。
为什么是这样一串奇怪的 16 进制? ObjectOutputStream#writeString(String str, boolean unshared) 实际就是标志位 + 字符串长度 + 字符串内容
KEY 被序列化成这样,线上通过 KEY 去查询对应的 VALUE非常不方便,所以 KEY 肯定是不能被这样序列化的。
VALUE 被序列化成这样,除了阅读可能困难一点,不支持跨语言外,实际上也没还OK。不过,实际线上场景,还是使用 JSON 序列化居多。
使用3也能实现效果
多了@class 属性,反序列化的对象的类型就可以从这里获取到。
@class 属性看似完美解决了反序列化后的对象类型,但是带来 JSON 字符串占用变大,所以实际项目中,我们很少采用 Jackson2JsonRedisSerializer
// hash 数据结构操作
org.springframework.data.redis.core.RedisTemplate#opsForHash
// list
org.springframework.data.redis.core.RedisTemplate#opsForList
// string
org.springframework.data.redis.core.RedisTemplate#opsForValue
// set
org.springframework.data.redis.core.RedisTemplate#opsForSet
// zset
org.springframework.data.redis.core.RedisTemplate#opsForZSet
一、opsForValue用法
set(String, Object)
get(String);
总结:set时value传的是什么类型,get后返回的就是什么类型。
二、opsForList用法
rightPush
leftPush
leftPushAll
range
key:字符串,value:可以是任意对象Object(例如String、具体对象如自定义类Student等),一个key可以分别先后添加多个value。