Requirements:
Home - Categories show ( using the cache - to improve efficiency - improving customer satisfaction)
1. To achieve the effect is as follows: (Jingdong - Home Categories)
First, the needs analysis
Table 1. The relationship is as follows: (from the association table - tb_item_cat)
the parent_id:
a Category: Default is 0
two classifications: a classification id
three classification: two categories id
2. How to receive JSON data (three-tier classification data) return? ★
Analysis:
The first classification -> contains two categories -> contains the three-tier classification (many many)!
① from the association table -!> Autocorrelation POJO objects (as used herein)
②Map receive a set -> Map <String, Map < String, List >>
Second, the back-end implementation (distributed framework)
1. The data layer - Mybatis
Note: Only add a special sql statement, the rest are reverse engineering!
1.1 ItemCatDao.java
public interface ItemCatDao {
// 根据父类id - 0 , 查询分类信息
List<ItemCat> selectByParentId(@Param("id") Long id);
}
ItemCatDao.xml 1.2 (Cause: classifying a fixed length)
<?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. The business layer - Spring
2.1 ItemCatService.java
public interface ItemCatService {
List<ItemCat> findByItemCat3(Long parentId);
}
ItemCatServiceImpl.java 2.2 (Key)
@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. View layer - SpringMVC
@RestController
@RequestMapping("/itemCat")
public class ItemCatController {
@Reference
private ItemCatService itemCatService;
@RequestMapping("/findByParentId.do")
public List<ItemCat> findByParentId(Long parentId) {
return itemCatService.findByItemCat3(parentId);
}
}
Third, the front-end implementation (AngularJS)
1. Load the initialization process (transfer parent_id = 0)
ng-init="findByParentId(0);"
2. Display the front traverse (move the mouse to remove)
Note: traversing name may be inconsistent, needs to change!
<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>