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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章