【小项目】Spring boot基于Redis缓存商城分类,商品信息(含源码下载)

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

初始化分类以及商品信息

    @Component
    public class InitGoodsRedisData implements ApplicationListener<ContextRefreshedEvent> {

        @Autowired
        private JedisPool jedisPool;

        @Override
        public void onApplicationEvent(ContextRefreshedEvent c)
        {
            Jedis jedis = jedisPool.getResource();
            if (jedis.scard(RCRedisKey.GOODS_CATEGORY) > 0)
            {
                System.out.println("已经缓存商品初始化数据***************");
                return;
            }
            Transaction transaction = jedis.multi();
            initCategoryData(transaction);
            initGoodsData(transaction);
            transaction.exec();
            jedis.close();
            System.out.println("写入商品初始化数据***************OK");
        }

        // 初始化商品分类
        private void initCategoryData(Transaction transaction)
        {
            transaction.sadd(RCRedisKey.GOODS_CATEGORY,
                    JSONObject.toJSONString(new CategoryVO(1, "手机")),
                    JSONObject.toJSONString(new CategoryVO(2, "平板")));
        }

        // 初始化商品信息
        private void initGoodsData(Transaction transaction)
        {

            // 手机
            Map<String, Double> phoneScoreMembers = new HashMap<String, Double>(5);

            String goods11 = JSONObject.toJSONString(new GoodsVO(11, 1, "Iphone X", 8388.00,
                    "https://img11.360buyimg.com/n5/s75x75_jfs/t9907/361/46671134/65420/7d66b903/59c47a15N36a2fc0d.jpg"));
            phoneScoreMembers.put(goods11, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 11 + "", goods11);

            String goods12 = JSONObject.toJSONString(new GoodsVO(12, 1, "Iphone8 P", 6688.00,
                    "https://img10.360buyimg.com/n5/s54x54_jfs/t7339/80/2994230157/58546/a4b72d95/59b85837N990db7d3.jpg"));
            phoneScoreMembers.put(goods12, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 12 + "", goods12);

            String goods13 = JSONObject.toJSONString(new GoodsVO(13, 1, "三星S8", 5688.00,
                    "https://img14.360buyimg.com/n5/s54x54_jfs/t5095/313/1561100036/253747/b2dfce2f/59119ddcNc7305e8b.jpg"));
            phoneScoreMembers.put(goods13, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 13 + "", goods13);

            String goods14 = JSONObject.toJSONString(new GoodsVO(14, 1, "小米MIX2", 3599.00,
                    "https://img13.360buyimg.com/n5/s54x54_jfs/t9214/51/1590664916/300151/a59b7cd3/59bb8691Naca717e9.jpg"));
            phoneScoreMembers.put(goods14, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 14 + "", goods14);

            String goods15 = JSONObject.toJSONString(new GoodsVO(15, 1, "华为P10", 3488.00,
                    "https://img14.360buyimg.com/n5/s54x54_jfs/t4333/208/365266204/337840/e9e7bd9a/58b3f51aN10566aa1.jpg"));
            phoneScoreMembers.put(goods15, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 15 + "", goods15);

            transaction.zadd(String.format(RCRedisKey.GOODS_LIST, 1), phoneScoreMembers);

            // 电脑
            Map<String, Double> computerScoreMembers = new HashMap<String, Double>(5);
            String goods21 = JSONObject.toJSONString(new GoodsVO(21, 2, "Apple iPad", 3258.00,
                    "https://img12.360buyimg.com/n5/s54x54_jfs/t3214/177/9256496777/621169/2a1735b5/58d16208N55e7302b.jpg"));
            computerScoreMembers.put(goods21, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 21 + "", goods21);

            String goods22 = JSONObject.toJSONString(new GoodsVO(22, 2, "华为M3", 2258.00,
                    "https://img10.360buyimg.com/n5/s54x54_jfs/t3235/143/2924985643/316383/370982db/57e8d527Ncb5ce343.jpg"));
            computerScoreMembers.put(goods22, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 22 + "", goods22);

            String goods23 = JSONObject.toJSONString(new GoodsVO(23, 2, "Apple iPad mini 4", 3098.00,
                    "https://img14.360buyimg.com/n5/s54x54_jfs/t9751/18/332152129/67998/3cef982f/59cc62ccN582dbd8a.jpg"));
            computerScoreMembers.put(goods23, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 23 + "", goods23);

            String goods24 = JSONObject.toJSONString(new GoodsVO(24, 2, "Apple iPad Pro", 5888.00,
                    "https://img10.360buyimg.com/n5/s54x54_jfs/t6679/178/76604977/301064/4e10cb22/5938ffa2Nb4d435f2.jpg"));
            computerScoreMembers.put(goods24, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 24 + "", goods24);

            String goods25 = JSONObject.toJSONString(new GoodsVO(25, 2, "Surface Pro", 9888.00,
                    "https://img10.360buyimg.com/n5/s54x54_jfs/t5617/321/1137763311/121847/b9326254/5923eb44Ndae8df59.jpg"));
            computerScoreMembers.put(goods25, 0d);
            transaction.hset(RCRedisKey.GOODS_INFO, 25 + "", goods25);

            transaction.zadd(String.format(RCRedisKey.GOODS_LIST, 2), computerScoreMembers);

        }

    }

实现Spring接口ApplicationListener(项目启动后执行初始化方法)。使用Redis事务控制分类,商品列表,商品详情信息的数据一致性。结合数据的访问情景,使用不同的Redis缓存方式。

  1. 商品分类:数据唯一,且一次性全部拿取,使用Set(集合)进行缓存
  2. 商品列表:数据具备排序支持,使用SortedSet(有序集合)进行缓存
  3. 商品详情:准确定位获取数据信息,使用Hash(哈希表)进行缓存

控制器以及业务处理类

    @Controller
    @RequestMapping("goods")
    public class GoodsController {

        @Autowired
        private GoodsBiz goodsBiz;

        @Autowired
        private HttpServletRequest request;

        // 获取分类列表
        @RequestMapping(value = "category")
        public String category() {
            request.setAttribute("pageData", goodsBiz.category());
            return "goods/category";
        }

        // 获取商品列表
        @RequestMapping(value = "goods_list")
        public String goodsList(@RequestParam Integer cid) {
            request.setAttribute("pageData", goodsBiz.goodsList(cid));
            return "goods/goods_list";
        }

        // 获取商品详情
        @RequestMapping(value = "goods_detail")
        public String goodsDetail(@RequestParam Integer gid) {
            request.setAttribute("info", goodsBiz.goodsDetail(gid));
            return "goods/goods_detail";
        }

    }
    @Service
    public class GoodsBiz {

        @Autowired
        private JedisPool jedisPool;

        // 获取分类列表
        public List<CategoryVO> category() {
            Jedis jedis = jedisPool.getResource();
            try {
                Set<String> cacheCategory = jedis.sunion(RCRedisKey.GOODS_CATEGORY);
                if (cacheCategory.isEmpty())
                    return null;
                List<CategoryVO> result = new ArrayList<CategoryVO>(cacheCategory.size());
                for (String item : cacheCategory)
                    result.add(JSONObject.parseObject(item, CategoryVO.class));
                return result;
            } finally {
                jedis.close();
            }
        }

        // 获取商品列表
        public List<GoodsListVO> goodsList(int categoryId) {
            Jedis jedis = jedisPool.getResource();
            try {
                Set<String> categoryGoods = jedis.zrevrange(String.format(RCRedisKey.GOODS_LIST, categoryId), 0, -1);
                if (categoryGoods.isEmpty())
                    return null;
                List<GoodsListVO> result = new ArrayList<GoodsListVO>(categoryGoods.size());
                for (String item : categoryGoods) {
                    GoodsListVO pCache = JSONObject.parseObject(item, GoodsListVO.class);
                    pCache.setScore(jedis.zscore(String.format(RCRedisKey.GOODS_LIST, categoryId), item).intValue());
                    result.add(pCache);
                }
                return result;
            } finally {
                jedis.close();
            }
        }

        // 获取商品详情
        public GoodsVO goodsDetail(Integer gid) {
            Jedis jedis = jedisPool.getResource();
            try {
                String cacheGoods = jedis.hget(RCRedisKey.GOODS_INFO, gid + "");
                if (cacheGoods == null)
                    return null;
                GoodsVO result = JSONObject.parseObject(cacheGoods, GoodsVO.class);
                jedis.zincrby(String.format(RCRedisKey.GOODS_LIST, result.getCategoryId()), 1, cacheGoods);
                return result;
            } finally {
                jedis.close();
            }
        }

    }

注:使用jedis注意close

获取商品列表使用ZREVRANGE根据缓存的序号倒序拿取

ZREVRANGE
命令使用:ZREVRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定区间内的成员。
其中成员的位置按 score 值递减 (从大到小) 来排列
具有相同 score 值的成员按字典序的逆序 排列

获取商品详情时使用ZINCRBY对商品缓存列表序号追加1

ZINCRBY
命令使用:ZINCRBY key increment member
为有序集 key 的成员 member 的 score 值加上增量 increment
可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是
让member 的 score 值减去 5 。
当 key 不存在,或 member 不是 key 的成员时,ZINCRBY key increment member 等同于 ZADD key
increment member 。
当 key 不是有序集类型时,返回一个错误。
score 值可以是整数值或双精度浮点数

页面展示

界面使用thymeleaf模版进行编辑

thymeleaf介绍
简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP 。相较与其他的模板引擎,它有如下三个极吸引人的特点:
1.Thymeleaf 在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。这是由于它支持 html 原型,然后在 html 标签里增加额外的属性来达到模板+数据的展示方式。浏览器解释 html 时会忽略未定义的标签属性,所以 thymeleaf 的模板可以静态地运行;当有数据返回到页面时,Thymeleaf 标签会动态地替换掉静态内容,使页面动态显示
2.Thymeleaf 开箱即用的特性。它提供标准和spring标准两种方言,可以直接套用模板实现JSTL、 OGNL表达式效果,避免每天套模板、该jstl、改标签的困扰。同时开发人员也可以扩展和创建自定义的方言
3.Thymeleaf 提供spring标准方言和一个与 SpringMVC 完美集成的可选模块,可以快速的实现表单绑定、属性编辑器、国际化等功能

信息参考:http://www.importnew.com/25826.html

列表页面

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
    <head>
    <meta charset="UTF-8" />
    <title>商品列表</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <link href="https://cdn.bootcss.com/Buttons/2.0.0/css/buttons.min.css" rel="stylesheet" />
    <style type="text/css"> .content_container { width: 1366px; } th { text-align: center; } </style>
    </head>
    <body class="container-fluid">
        <div class="content_container center-block" style="text-align: center; margin-top: 30px;">
            | 编号|名称|图片|价格|浏览量|操作|
| :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | 
|  |  |  |  |  | 查看 | 

            <a class="button" th:href="@{category}">返回分类</a>
        </div>
    </body>
    </html>

HTML页面需引用thymeleaf标签声明,Eclipse对thymeleaf标签插件支持地址:http://www.thymeleaf.org/eclipse-plugin-update-site/(Eclipse->Help->Install New Software)

页面展示
20191102100490\_1.png

此项目缓存思路不仅限于商城,适用于所有类似的业务缓存

项目源码下载(2分):http://download.csdn.net/download/qq_19260029/10022078

更多文章:
Java基于Redis实现“附近的人”
Eclipse新建Spring-boot项目,打包部署并输出HelloWord


来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【小项目】Spring boot基于Redis缓存商城分类,商品信息(含源码下载)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏