配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
spring.redis.database=0
## Redis\u670D\u52A1\u5668\u5730\u5740
spring.redis.host=192.168.1.138
## Redis\u670D\u52A1\u5668\u8FDE\u63A5\u7AEF\u53E3
spring.redis.port=6379
redis配置:
@Configuration
public class RedisConfiguration {
/**
* 重写Redis序列化方式,使用Json方式:
* 当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到Redis的。
* RedisTemplate默认使用的是JdkSerializationRedisSerializer,
* StringRedisTemplate默认使用的是StringRedisSerializer。
*
* Spring Data JPA为我们提供了下面的Serializer:
* GenericToStringSerializer、Jackson2JsonRedisSerializer、
* JacksonJsonRedisSerializer、JdkSerializationRedisSerializer、
* OxmSerializer、StringRedisSerializer。
* 在此我们将自己配置RedisTemplate并定义Serializer。
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//创建一个json的序列化对象
GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
//设置value的序列化方式json
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
//设置key序列化方式string
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置hash key序列化方式string
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//设置hash value的序列化方式json
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
实体层
购物车
@Data
public class Cart {
private Long userId;
private Long productId;
private int amount;
}
@Data
public class CartPage<T> {
private List<T> cartList;
private int count;
}
商品
@Data
public class Product {
private Long id;
/**
* 产品名称
*/
private String name;
/**
* 产品价格
*/
private Integer price;
/**
* 产品详情
*/
private String detail;
}
控制层
商品控制层:
@RestController
@Slf4j
@RequestMapping(value = "/pruduct")
public class ProductController {
@Autowired
private RedisTemplate redisTemplate;
@PostMapping(value = "/create")
public void create(Product obj) {
//TODO 先进db
//创建商品,先把数据添加到数据库,再存入redis
String key="product:"+1000;
//将Object对象里面的属性和值转化成Map对象
Map<String, Object> map=this.objectToMap(obj);
//批量put操作 putAll 等于 hmset命令
//String数据结构opsForValue hash数据结构opsForHash
this.redisTemplate.opsForHash().putAll(key,map);
Object name=this.redisTemplate.opsForHash().get(key,"name");
log.info("name={}",name);
Object price=this.redisTemplate.opsForHash().get(key,"price");
log.info("price={}",price);
Object detail=this.redisTemplate.opsForHash().get(key,"detail");
log.info("detail={}",detail);
}
@PostMapping(value = "/addPrice")
public void addPrice(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);
}
/**
* 将Object对象里面的属性和值转化成Map对象
*/
public Map<String, Object> objectToMap(Object obj) {
Map<String, Object> map = new HashMap<String,Object>();
Class<?> clazz = obj.getClass();
for (Field field : clazz.getDeclaredFields()) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = null;
try {
value = field.get(obj);
} catch (IllegalAccessException e) {
log.error(e.getMessage());
}
map.put(fieldName, value);
}
return map;
}
}
购物车控制层:
RestController
@Slf4j
@RequestMapping(value = "/cart")
public class UserCartController {
@Autowired
private RedisTemplate redisTemplate;
/**
* 购物车key的前缀
*/
public static final String CART_KEY = "cart:user:";
/**
* 添加购物车
*/
@PostMapping(value = "/addCart")
public void addCart(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);
}
//TODO 发rabbitmq 出去
}
/**
* 修改购物车的数量
*/
@PostMapping(value = "/updateCart")
public void updateCart(Cart obj) {
String key = CART_KEY + obj.getUserId();
this.redisTemplate.opsForHash().put(key, obj.getProductId().toString(), obj.getAmount());
//TODO 发rabbitmq 出去
}
/**
*删除购物车
*/
@PostMapping(value = "/delCart")
public void delCart(Long userId, Long productId) {
String key = CART_KEY + userId;
this.redisTemplate.opsForHash().delete(key, productId.toString());
//TODO 发rabbitmq 出去
}
@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以后的购物车:
@Data
public class CookieCart {
private Long productId;
private int amount;
}
@RestController
@Slf4j
@RequestMapping(value = "/cookiecart")
public class CookieCartController {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private IdGenerator idGenerator;
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
public static final String COOKIE_KEY = "cart:cookie:";
/**
* 添加购物车
*/
@PostMapping(value = "/addCart")
public void addCart(CookieCart obj) {
String cartId=this.getCookiesCartId();
String key=COOKIE_KEY+cartId;
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(CookieCart obj) {
String cartId=this.getCookiesCartId();
String key=COOKIE_KEY+cartId;
this.redisTemplate.opsForHash().put(key, obj.getProductId().toString(),obj.getAmount());
}
/**
* 删除购物车
*/
@PostMapping(value = "/delCart")
public void delCart(Long productId) {
String cartId=this.getCookiesCartId();
String key=COOKIE_KEY+cartId;
this.redisTemplate.opsForHash().delete(key, productId.toString());
}
/**
* 查询某个用户的购物车
*/
@PostMapping(value = "/findAll")
public CartPage findAll() {
String cartId=this.getCookiesCartId();
String key=COOKIE_KEY+cartId;
CartPage<CookieCart> cartPage=new CartPage();
//查询该用户购物车的总数
long size=this.redisTemplate.opsForHash().size(key);
cartPage.setCount((int)size);
//查询购物车的所有商品
Map<String,Integer> map= this.redisTemplate.opsForHash().entries(key);
List<CookieCart> cartList=new ArrayList<>();
for (Map.Entry<String,Integer> entry:map.entrySet()){
CookieCart cart=new CookieCart();
cart.setProductId(Long.parseLong(entry.getKey()));
cart.setAmount(entry.getValue());
cartList.add(cart);
}
cartPage.setCartList(cartList);
return cartPage;
}
/**
* 获取cookies
*/
public String getCookiesCartId(){
//第一步:先检查cookies是否有cartid
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("cartId")){
return cookie.getValue();
}
}
}
//第二步:cookies没有cartid,直接生成全局id,并设置到cookie里面
//生成全局唯一id
long id=this.idGenerator.incrementId();
//设置到cookies
Cookie cookie=new Cookie("cartId",String.valueOf(id));
response.addCookie(cookie);
return id+"";
}
/**
* 合并购物车
* 把cookie中的购物车合并到登录用户的购物车
*/
@PostMapping(value = "/mergeCart")
public void mergeCart(Long userId) {
//第一步:提取未登录用户的cookie的购物车数据
String cartId=this.getCookiesCartId();
String keycookie=COOKIE_KEY+cartId;
Map<String,Integer> map= this.redisTemplate.opsForHash().entries(keycookie);
//第二步:把cookie中得购物车合并到登录用户的购物车
String keyuser = "cart:user:" + userId;
this.redisTemplate.opsForHash().putAll(keyuser,map);
//第三步:删除redis未登录的用户cookies的购物车数据
this.redisTemplate.delete(keycookie);
//第四步:删除未登录用户cookies的cartid
Cookie cookie=new Cookie("cartId",null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
id生成工具:
@Service
public class IdGenerator {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final String ID_KEY = "id:generator:cart";
/**
* 生成全局唯一id
*/
public Long incrementId() {
long n=this.stringRedisTemplate.opsForValue().increment(ID_KEY);
return n;
}
}