一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情。
Hash是什么
redis的hash数据结构,其实就是string的升级版,它把string数据结构的key,value 中的value类型升级位hash(和Java的hash结构一样的结构) HashMap<String,HashMap<String,String>>();
每个hash的存储大小:可以存储2的(32-1)方的键值对(40多亿)
Redis存储Java对象常用String,那为什么还要hash来存储呢?
Redis存储Java对象,一般是String或Hash两种,什么时候用String?什么时候用Hash呢?
String的存储通常用在频繁操作,它的存储格式是json,即把java对象转换为json,然后存入redis.
Hash的存储场景应用在频繁写操作,即,当对象的某个属性频繁修改时,不适用string+json的数据结构,因为不灵活,每次修改都需要把整个对象转换为json存储。如果采用hash,就可以针对某个属性单独修改,不用序列号去修改整个对象。例如,商品的库存、价格、关注数、评价数经常变动时,就使用存储hash结果。 例如:购物车
常用命令
HSET key field value
将哈希表key中的字段field的值设为value。
HGET key field
获取存储在哈希表中指定字段的值
hset product:100 name iphone11
hget product:100 name
HMSET key field1 value1 [field2 value2]
同时将多个 field-value (域-值)对设置到哈希表 key 中。
HMGET key field1 [field2 field3 ...]
获取所有给定字段的值
hmset product:100 price 5000 detail "I love xiaomi"
hmget produc:100 name price datail
HKEYS key
获取指定hash中所有field值
hkeys product:100
HVALS key
获取指定hash中所有value值
hvals product:100
HGETALL key
获取指定hash中所有field、value值
hgetall product:100
HLEN key
获取指定hash中元素的个数
hlen product:100
HINCRBY key field data(整形)
给指定field 对应的value值加上data数组
HINCRBYFLOAT key field data(浮点数)
给指定 field 对应的 value 值加上 data 数值
hincrby product:100 price 100
hgetall product:100
HEXISTS key field
检查指定的field是否存在
hexists product:100 name
HDEL key field1 [field2 fiedl3 ...]
删除一个或多个哈希表字段
hdel product:100 name
hgetall product:100
案例:Springboot+redis+hash存储商品数据
入门Hash
- 加入依赖包
- 创建商品的redis处理数据
//参数:Product obj
//TODO 先进db
//创建商品,先把数据添加到数据库,再存入redis
//key:"前缀"+商品id
//批量put操作,puttAll 等于 hmset命令
this.redisTemplate.opsForHash().putAll(key,map);
//根据key获取数据 hget key field命令
Object name=this.redisTemplate.opsForHash().get(key,"name");
log.info("name={}",name);
商品涨价
//参数:int id,int price
String key="product:"+id;
//商品价格涨价 increment等于 hincrby命令
this.redisTemplate.opsForHash().increment(key,"price",price);
Object price2=this.redisTemplate.opsForHash().get(key,"price");
log.info("price={}",price2);
购物车功能
前提要求:用户已经登录的情况下
购物车涉及高并发,会出现数据一致性问题。这块后期讲。
一、购物车场景分析
步骤1:先登录你的京东账号,清空以前购物车,然后添加一件商品A,保证你的购物车只有一件商品A。
步骤2:退出登录,购物车添加商品B,然后关闭游览器再打开。(请问:购物车的商品B是否存在?)存在
步骤3:再次登录你的京东账号,(请问:你的购物车有几件商品)
二、图解分析(欠着)
三、redis实现 往购物车加入2件商品 采用hash数据结果,key=cart:user:用户id
hset cart:user:1000 101 1
hset cart:user:1000 102 1
hgetall cart:user:1000
修改购物车的数据,为某件商品添加数量
hincrby cart:user:1000 101 1
hincrby cart:user:1000 102 10
hgetall cart:user:1000
统计购物车有多少件商品
hlen cart:user:1000
删除购物车某件商品
hdel cart:user:1000 102
hgetall cart:user:1000
四、Java代码
步骤1:登录状态下添加商品到购物车
①、添加购物车
@PostMapping(value = "/addCart")
public void addCart(@RequestBody Cart obj) {
String key = CART_KEY + obj.getUserId();
Boolean hasKey = redisTemplate.opsForHash().getOperations().hasKey(key);
//存在
if(hasKey){
this.redisTemplate.opsForHash().put(key, obj.getProductId().toString(), obj.getAmount());
}else{
this.redisTemplate.opsForHash().put(key, obj.getProductId().toString(), obj.getAmount());
this.redisTemplate.expire(key,90, TimeUnit.DAYS);
}
}
②修改购物车的数量
@PostMapping(value = "/updateCart")
public void updateCart(@RequestBody Cart obj) {
String key = CART_KEY + obj.getUserId();
this.redisTemplate.opsForHash().put(key, obj.getProductId().toString(), obj.getAmount());
}
③删除购物车
@PostMapping(value = "/delCart")
public void delCart(Long userId, Long productId) {
String key = CART_KEY + userId;
this.redisTemplate.opsForHash().delete(key, productId.toString());
}
④查询购物车
@PostMapping(value = "/findAll")
public CartPage findAll(Long userId) {
String key = CART_KEY + userId;
CartPage cartPage = new CartPage();
//查购物车的总数
long size = this.redisTemplate.opsForHash().size(key);
cartPage.setCount((int) size);
//查询购物车的所有商品
//entries=hgetall命令
Map<String, Integer> map = this.redisTemplate.opsForHash().entries(key);
List<Cart> cartList = new ArrayList<>();
for (Map.Entry<String, Integer> entry : map.entrySet()) {
Cart cart = new Cart();
cart.setUserId(userId);
cart.setProductId(Long.parseLong(entry.getKey()));
cart.setAmount(entry.getValue());
cartList.add(cart);
}
cartPage.setCartList(cartList);
return cartPage;
}
后续写 cookie+redis 实现不登录的前提下 实现加入数据。
淘宝短链接 如何设计 有什么好处 什么算法实现的?
《短链接转换器》的原理:
- 长链接转换为短链接 实现原理:长链接转换为短链接加密串key,然后存储于redis的hash结构中。
- 重定向到原始的url 实现原理:通过加密串key到redis找出原始url,然后重定向出去