IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> springboot/redisTemplate做购物车缓存 -> 正文阅读

[大数据]springboot/redisTemplate做购物车缓存

记录下第一次在springboot 用redis

未完待续...

RedisConfig

@Configuration
@EnableCaching
public class RedisConfig
{

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
    {
        //自定义redisTemplate
        // RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>();
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        // 配置连接工厂
        template.setConnectionFactory(redisConnectionFactory);

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        //这里对Object.class可以为自己的类
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        //设置时间转换
        LocalDateTimeDeserializer localDateTimeDeserializer = new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDateTime.class, localDateTimeDeserializer);
        mapper.registerModule(javaTimeModule);

        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }


    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory)
    {

        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        config = config.entryTtl(Duration.ofMinutes(60*60*24*4));
        /*config = config.entryTtl(Duration.ofHours(1));*/


        // 设置一个初始化的缓存空间set集合
        Set<String> cacheNames =  new HashSet<>();
        cacheNames.add("car");
        cacheNames.add("userInfo");

        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        //entryTtl设置缓存失效时间,单位是秒
        configMap.put("car",  config.entryTtl(Duration.ofSeconds(60*60)));
        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)
                .initialCacheNames(cacheNames)
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    /**
     * 对hash类型的数据操作
     * @return
     */

    @Bean
    public HashOperations<Object, Object, Object> hashOperations(RedisTemplate<Object,Object> redisTemplate)
    {
        return redisTemplate.opsForHash();
    }

    /**
     * 对redis字符串类型数据库操作
     * @return
     */
    @Bean
    public ValueOperations<Object, Object> valueOperations(RedisTemplate<Object, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }

购物车jsp


<c:forEach items="${shopingList}" var="goods" varStatus="i">
    <div class="goods-item" id="item${i}">
        <div class="panel panel-default">
            <div class="panel-body">
                <div class="col-md-3 col-sm-2 col-xs-2 car-goods-info goods-image-column">
                    <a href="goodsDetail.html">
                        <img class="goods-image" src="${goods.firstPic}" />
                    </a>
                </div>
                <div class="col-md-3 col-sm-2 col-xs-2 car-goods-info goods-params">
                    <p class="goods-info" id="goodsNum" value="${goods.gName}">
                        ${goods.gName}
                    </p>
                </div>
                <div class="col-md-1 col-sm-2 col-xs-2 car-goods-info goods-price">
                    <span class="goods-price single-price">¥${goods.gPrice}</span></div>
                <div class="col-md-2 col-sm-2 col-xs-2 car-goods-info goods-counts">
                    <div class="input-group">
                        <div class="input-group-btn">
                            <button type="button"
                                    class="goods-sub btn btn-default car-decrease myadd minue" value="${i.count}" onclick="updateNum(0,${i.count},${goods.cGoodId},${goods.cPrice})" >-</button>
                        </div>
                        <input type="text" disabled class="goods-num form-control goods-count myaddNum"
                               value="${goods.cnum}" id="num${i.count}">


                        <div class="input-group-btn">
                            <button type="button" id="addNum"
                                    class="goods-add btn btn-default car-add myadd plus" value="${i.count}" onclick=updateNum(1,${i.count},${goods.cGoodId},${goods.cPrice}) >+</button>
                        </div>
                      <
                    </div>
                </div>
                <div class="col-md-1 col-sm-2 col-xs-2 car-goods-info goods-money-count">
                    <span class="goods-totalMoney single-total" id="totalPrice">¥${goods.cnum*goods.gPrice}</span></div>
                <div class="col-md-2 col-sm-2 col-xs-2 car-goods-info goods-operate">
                    <a href="waitPay.html" class="btn btn-primary">结算</a>
                    <a data-toggle="modal" data-target=".bs-example-modal-sm" href="#"
                       class="btn btn-danger item-delete">删除</a>
                </div>
            </div>
        </div>
    </div>


</c:forEach>
<script>

   //总共需要上传的数据数组
   const updateData = new Array(50);
    function updateNum(flag,count,gId,price)
    {
        var num1 = $("#num"+count).val();
        var num = Number(num1);
        //判断点击的是+还是- 更新数据
        num=(flag===1)? (num+1) : (num-1);
        //用来传给后台的json
        var updateThisG =
        {
            "count":count,
            "newNum": num,
            "gId": gId
        }
        var Jupdata = JSON.stringify(updateThisG);

        $.ajax
        (
            {
                url: "/shop/addNum2",
                data: Jupdata,
                type:'POST',//默认为get请求,这里设置为post请求
                contentType:'application/json;charset=UTF-8',
                success: function(res)
                {
                    //修改更改数量后的价格
                    price = res*price
                    $("#totalPrice").html("¥"+price);
                    //回显修改后的num
                    $("#num"+count).val(num);
                    console.log("这是第 "+count+ " 次修改商品数量,修改的goodsid是: "+gId+" 修改的数量是: "+num);
                },
                error(res)
                {

                }
            }
        )

    }
</script>                         
goodsServiceImpl

@Override
    public List<HashMap> getCarByUId(Long uid)
    {
        //判断redis里有没有该uid的购物车
        if(redisService.hasUidCar(uid))
        {
            return redisService.queryCarInfoByUid(uid);
        }
        //redis里没有购物车,则查询数据库
        List<HashMap> carInfo = userMapper.getCarByUid(uid);
        //信息存入redis
        redisService.setToRedis(carInfo,uid);

        return carInfo;

    }

RedisService

@Service
public class RedisService
{
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisUtil redisUtil;



//将购物车list存入redis
    public void setToRedis(List<HashMap> carInfo,Long uid)
    {

        redisUtil.setCacheList("car:userId:"+uid,carInfo);
    }
//修改购物车中商品的数量,并更新redis
    public void updateNum(JSONObject jupdata,Long userId)
    {
        //当前需要修改的下标
        int count = (int) jupdata.get("count");
        //更新后的数据
        int updateNum = (int) jupdata.get("newNum");
        //redis的key
        String keyI = "car:userId:"+userId;
        //拿到该key的所有value
        List<HashMap> list =  redisTemplate.opsForList().range(keyI,0,-1);
        //对需要修改的map进行修改
        HashMap map = list.get(count-1);

        if (map.containsKey("cnum"))
        {
            map.put("cnum",updateNum);
        }
        //修改后的map放入list
        list.set(count-1,map);

        //删除原有list并放回新的list
        redisTemplate.delete("car:userId:"+userId);
        redisUtil.setCacheList("car:userId:"+userId,list);

    }

//判断该uid在redis有没有存购物车信息
    public boolean hasUidCar(Long uid)
    {
       return redisTemplate.hasKey("car:userId:"+uid);
    }

//打开购物车页面前,判断若redis存在该uid的购物车信息则调用该方法
    public List<HashMap> queryCarInfoByUid(Long uid)
    {
        String keyI = "car:userId:"+uid;
        return redisTemplate.opsForList().range(keyI,0,-1);
    }

   
}


util:
/**
     * 缓存List数据
     *
     * @param key 缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList)
    {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }
shop:增加、减少购物车某商品数量的controller

 @RequestMapping("/addNum2")
    public void add2(HttpServletRequest request, @RequestBody JSONObject jupdata,HttpServletResponse response) throws IOException 
    {
        //当前用户id
        //获取用户id
        TUser loginedUser = (TUser) request.getSession().getAttribute("loginedUser");
        Long userId = loginedUser.getId();
        //修改redis
        redisService.updateNum(jupdata,userId);
        //更新后的数据
        int updateNum = (int) jupdata.get("newNum");
        response.getWriter().write(updateNum);

    }

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:14:50  更:2021-09-26 10:16:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:49:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码