redis+springboot实现购物车+商品数据修改实例


配置:

  <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;
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 引入依赖 在 `pom.xml` 文件中引入 Redis 和 Spring Boot 相关的依赖: ```xml <!-- Redis 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency> <!-- Spring Boot 相关依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 2. 配置 Redis 在 `application.properties` 文件中配置 Redis: ```properties # Redis 配置 spring.redis.host=localhost spring.redis.port=6379 spring.redis.database=0 ``` 3. 编写代码 在 Spring Boot 项目中编写 Controller 类,实现日访问量统计的功能。 ```java @RestController public class VisitController { private final String KEY = "visit_count"; @Autowired private StringRedisTemplate redisTemplate; @GetMapping("/visit") public String visit() { // 获取当前日期 String today = LocalDate.now().toString(); // 计数器自增 Long count = redisTemplate.opsForHash().increment(KEY, today, 1); // 返回结果 return "今日访问量:" + count; } @GetMapping("/visit/count") public String getCount() { // 获取当前日期 String today = LocalDate.now().toString(); // 获取访问量 Object value = redisTemplate.opsForHash().get(KEY, today); Long count = value != null ? Long.parseLong(value.toString()) : 0L; // 返回结果 return "今日访问量:" + count; } } ``` 在上述代码中,我们使用 Redis 的 Hash 数据结构来存储每天的访问量。`visit` 方法用于增加访问量,`getCount` 方法用于获取当前日期的访问量。 4. 测试 启动 Spring Boot 项目后,访问 `http://localhost:8080/visit` 可以增加访问量,访问 `http://localhost:8080/visit/count` 可以获取当前日期的访问量。 注意:上述代码中只是一个简单的示例,实际应用中还需要考虑并发访问的情况,可以使用 Redis 的分布式锁来解决

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值