Java实现仿京东/淘宝首页商品分类的展示!

需求:
        网站首页 - 商品分类展示( 使用缓存 - 提高效率 - 提高用户满意度 )

1.实现效果如下: (京东-首页分类)
在这里插入图片描述

一、需求分析

在这里插入图片描述

1.表关系如下: ( 自关联表 - tb_item_cat )

parent_id:
                 一级分类: 默认是 0
                 二级分类: 一级分类的id
                 三级分类: 二级分类的id
在这里插入图片描述

2.如何接收返回的JSON数据(三级分类数据)? ★

分析:
        一级分类   ->   包含二级分类   ->   包含三级分类!           ( 一对多对多 )

①自关联表 -> 自关联POJO对象! ( 本文使用 )
在这里插入图片描述
②Map集合接收 -> Map<String , Map<String , List>>
在这里插入图片描述

二、后端实现( 分布式框架 )

1.数据层 - Mybatis

                                注: 只添加了特殊的sql语句 , 其余都是逆向工程!

1.1 ItemCatDao.java

public interface ItemCatDao {
    // 根据父类id - 0 , 查询分类信息
    List<ItemCat> selectByParentId(@Param("id") Long id);
}

1.2 ItemCatDao.xml ( 原因: 固定一级分类的长度 )
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.xxx.dao.item.ItemCatDao" >

  <!-- 查询三级分类信息 -->
  <select id="selectByParentId" resultType="cn.xxx.pojo.item.ItemCat">
    SELECT * FROM tb_item_cat WHERE parent_id = #{id} LIMIT 15
  </select>
  
</mapper>
2.业务层 - Spring

2.1 ItemCatService.java

public interface ItemCatService {
	List<ItemCat> findByItemCat3(Long parentId);
}

2.2 ItemCatServiceImpl.java ( 重点 )

@Service
public class ItemCatServiceImpl implements ItemCatService {

    @Resource
    private ItemCatDao itemCatDao;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Override
    public List<ItemCat> findByItemCat3(Long parentId01) {
        // 1.先从redis缓存中 , 获取三级分类信息!
        List<ItemCat> itemCat01List  = (List<ItemCat>) redisTemplate.boundValueOps("itemCat03").get();

        // 2.若缓存中没有数据 , 从数据库中查询( 并放到缓存中 )
        if (itemCat01List==null){
            // 缓存穿透 -> 请求排队等候.
            synchronized (this){
                // 进行二次校验?
                itemCat01List  = (List<ItemCat>) redisTemplate.boundValueOps("itemCat03").get();
                if (itemCat01List==null){
                    // 创建一个集合 , 存放一级分类
                    itemCat01List = new ArrayList<>();

                    // 根据parent_id = 0 , 获取一级分类信息!
                    List<ItemCat> itemCatList = itemCatDao.selectByParentId(parentId01);
                    for (ItemCat itemCat : itemCatList) {
                        // 设置一级分类信息!
                        ItemCat itemCat01 = new ItemCat();
                        itemCat01.setId(itemCat.getId());
                        itemCat01.setName(itemCat.getName());
                        itemCat01.setParentId(itemCat.getParentId());

                        // 根据一级分类的id -> 找到对应的二级分类!
                        List<ItemCat> itemCatList02 = new ArrayList<>();
                        ItemCatQuery itemCatQuery02 = new ItemCatQuery();
                        itemCatQuery02.createCriteria().andParentIdEqualTo(itemCat.getId());
                        List<ItemCat> itemCat02List = itemCatDao.selectByExample(itemCatQuery02);
                        for (ItemCat itemCat2 : itemCat02List) {
                            // 设置二级分类信息!
                            ItemCat itemCat02 = new ItemCat();
                            itemCat02.setId(itemCat2.getId());
                            itemCat02.setName(itemCat2.getName());
                            itemCat02.setParentId(itemCat2.getParentId());


                            // 根据二级分类的id -> 找到对应的三级分类!
                            List<ItemCat> itemCatList03 = new ArrayList<>();
                            ItemCatQuery itemCatQuery03 = new ItemCatQuery();
                            itemCatQuery03.createCriteria().andParentIdEqualTo(itemCat02.getId());
                            List<ItemCat> itemCat03List = itemCatDao.selectByExample(itemCatQuery03);
                            for (ItemCat itemCat3 : itemCat03List) {
                                itemCatList03.add(itemCat3);
                            }
                            itemCat02.setItemCatList(itemCatList03);  // 二级分类中 添加 三级分类.
                            itemCatList02.add(itemCat02);       // 添加二级分类.
                        }
                        itemCat01.setItemCatList(itemCatList02); // 一级分类中 添加 二级分类!
                        itemCat01List.add(itemCat01);  // 添加一级分类
                    }
                    // 将查询到的数据放入缓存中!
                    redisTemplate.boundValueOps("itemCat03").set(itemCat01List);
                    return itemCat01List;
                }
            }

        }

        // 3.若缓存中有数据 , 直接返回即可!
        return itemCat01List;
    }

}

3.视图层 - SpringMVC
@RestController
@RequestMapping("/itemCat")
public class ItemCatController {

    @Reference
    private ItemCatService itemCatService;

    @RequestMapping("/findByParentId.do")
    public List<ItemCat> findByParentId(Long parentId) {
        return itemCatService.findByItemCat3(parentId);
    }
}

三、前端实现( angularjs )

1.初始化加载方法( 传递parent_id = 0 )
ng-init="findByParentId(0);" 

在这里插入图片描述

2.前端遍历展示( 鼠标移入移除 )

注: 遍历名称可能不一致 , 需要改变!

<div class="yui3-u Left all-sort-list">
    <div class="all-sort-list2">
        <div class="item {{flag?'hover':''}}" ng-repeat="itemCat1 in list" ng-mouseenter="flag=true"
             ng-mouseleave="flag=false">
            <h3><a href="">{{itemCat1.name}}</a></h3>
            <!--通过三元表达式确定是显示还是隐藏-->
            <div class="item-list clearfix" style="display: {{flag?'block':'none'}}">
                <div class="subitem">
                    <!--遍历2级分类-->
                    <dl class="fore1" ng-repeat="itemCat2 in itemCat1.itemCat02List">
                        <dt><a href="">{{itemCat2.name}}</a></dt>
                        <dd>
                            <!--遍历3级分类-->
                            <em ng-repeat="itemCat3 in itemCat2.itemCat03List">
                                <a href="">{{itemCat3.name}}</a>
                            </em>
                        </dd>
                    </dl>
                </div>
            </div>
        </div>

    </div>
</div>
发布了107 篇原创文章 · 获赞 173 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_42986107/article/details/86558331