1、商城项目商品服务三级分类缓存优化

pull/254/head
xjs 4 years ago
parent 09132426e4
commit 7495a0eca1

@ -8,7 +8,7 @@ package com.xjs.consts;
*/ */
public class RedisConst { public class RedisConst {
//----------------------key------------------------ //----------------------bussiness-key------------------------
/** /**
* key * key
@ -59,7 +59,25 @@ public class RedisConst {
* weixin.link * weixin.link
*/ */
public static final String REPTILE_WEIXIN_LINK_COUNT = "reptile:weixin.link.count"; public static final String REPTILE_WEIXIN_LINK_COUNT = "reptile:weixin.link.count";
;
//--------------------------mall-key-----------------------------------
/**
* mallKey
*/
public static final String MALL_PREFIX = "mall:";
/**
* key
*/
public static final String CATALOG_AFTER = MALL_PREFIX + "catalog:after";
/**
* key
*/
public static final String CATALOG_BEFORE = MALL_PREFIX + "catalog:before";
//-------------------有效时间----------------------- //-------------------有效时间-----------------------
public static final Integer TRAN_DICT_EXPIRE = 1; //小时 public static final Integer TRAN_DICT_EXPIRE = 1; //小时

@ -10,12 +10,16 @@ import com.xjs.validation.group.UpdateGroup;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import static com.xjs.consts.RedisConst.CATALOG_AFTER;
import static com.xjs.consts.RedisConst.CATALOG_BEFORE;
/** /**
* *
@ -30,6 +34,8 @@ import java.util.List;
public class CategoryController { public class CategoryController {
@Autowired @Autowired
private CategoryService categoryService; private CategoryService categoryService;
@Autowired
private StringRedisTemplate stringRedisTemplate;
/** /**
* -- * --
@ -84,6 +90,8 @@ public class CategoryController {
@Log(title = "商品分类", businessType = BusinessType.UPDATE) @Log(title = "商品分类", businessType = BusinessType.UPDATE)
public R updateSort(@RequestBody CategoryEntity[] categoryEntities) { public R updateSort(@RequestBody CategoryEntity[] categoryEntities) {
categoryService.updateBatchById(Arrays.asList(categoryEntities)); categoryService.updateBatchById(Arrays.asList(categoryEntities));
//删除缓存
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
return R.ok(); return R.ok();
} }

@ -3,8 +3,6 @@ package com.xjs.mall.product.controller.web;
import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.entity.CategoryEntity;
import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.service.CategoryService;
import com.xjs.mall.product.vo.Catelog2Vo; import com.xjs.mall.product.vo.Catelog2Vo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -15,13 +13,12 @@ import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
* * -
* *
* @author xiejs * @author xiejs
* @since 2022-04-07 * @since 2022-04-07
*/ */
@Controller @Controller
@Api(tags = "商城-商品-首页")
public class IndexController { public class IndexController {
@Autowired @Autowired
@ -37,7 +34,6 @@ public class IndexController {
@GetMapping("/index/json/catalog.json") @GetMapping("/index/json/catalog.json")
@ResponseBody @ResponseBody
@ApiOperation("获取三级分类")
public Map<String,List<Catelog2Vo>> getCatalogJson() { public Map<String,List<Catelog2Vo>> getCatalogJson() {
return categoryService.getCatalogJson(); return categoryService.getCatalogJson();
} }

@ -1,13 +1,24 @@
package com.xjs.mall.product.service.impl; package com.xjs.mall.product.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.utils.StringUtils;
import com.xjs.exception.MallException;
import com.xjs.mall.product.dao.CategoryDao; import com.xjs.mall.product.dao.CategoryDao;
import com.xjs.mall.product.entity.AttrEntity;
import com.xjs.mall.product.entity.AttrGroupEntity;
import com.xjs.mall.product.entity.CategoryBrandRelationEntity;
import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.entity.CategoryEntity;
import com.xjs.mall.product.service.AttrGroupService;
import com.xjs.mall.product.service.AttrService;
import com.xjs.mall.product.service.CategoryBrandRelationService; import com.xjs.mall.product.service.CategoryBrandRelationService;
import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.service.CategoryService;
import com.xjs.mall.product.vo.Catelog2Vo; import com.xjs.mall.product.vo.Catelog2Vo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -15,6 +26,9 @@ import javax.annotation.Resource;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.xjs.consts.RedisConst.CATALOG_AFTER;
import static com.xjs.consts.RedisConst.CATALOG_BEFORE;
@Service("categoryService") @Service("categoryService")
@Transactional @Transactional
@ -26,26 +40,78 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
@Autowired @Autowired
private CategoryBrandRelationService categoryBrandRelationService; private CategoryBrandRelationService categoryBrandRelationService;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private AttrGroupService attrGroupService;
@Autowired
private AttrService attrService;
@Override @Override
public List<CategoryEntity> listWithTree() { public List<CategoryEntity> listWithTree() {
//1、查询所有分类 //查缓存
List<CategoryEntity> entities = categoryDao.selectList(null); String cache = stringRedisTemplate.opsForValue().get(CATALOG_AFTER);
if (StringUtils.isEmpty(cache)) {
//1、查询所有分类
List<CategoryEntity> entities = categoryDao.selectList(null);
//2、找到所有一级分类
List<CategoryEntity> collect = entities.stream()
.filter(categoryEntity -> categoryEntity.getParentCid() == 0)
.peek(menu -> menu.setChildren(this.getChildrens(menu, entities)))
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
.collect(Collectors.toList());
//存入缓存
String jsonString = JSON.toJSONString(collect);
stringRedisTemplate.opsForValue().set(CATALOG_AFTER, jsonString);
//2、找到所有一级分类 return collect;
return entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0)
.peek(menu -> menu.setChildren(this.getChildrens(menu, entities)))
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
.collect(Collectors.toList());
} else {
return JSON.parseObject(cache, new TypeReference<List<CategoryEntity>>() {
});
}
} }
@Override @Override
public void removeMenuByIds(List<Long> asList) { public void removeMenuByIds(List<Long> asList) {
// todo 检查当前要删除的菜单是否被其他的地方引用 //检查当前要删除的菜单是否被其他的地方引用
for (Long id : asList) {
// 1、品牌关联
LambdaQueryWrapper<CategoryBrandRelationEntity> wrapperBrand = new LambdaQueryWrapper<CategoryBrandRelationEntity>()
.eq(CategoryBrandRelationEntity::getCatelogId, id);
List<CategoryBrandRelationEntity> relationEntityList = categoryBrandRelationService.list(wrapperBrand);
if (CollUtil.isNotEmpty(relationEntityList)) {
throw new MallException("请先删除关联品牌信息");
}
// 2、属性分组关联
LambdaQueryWrapper<AttrGroupEntity> wrapperAttrGroup = new LambdaQueryWrapper<AttrGroupEntity>()
.eq(AttrGroupEntity::getCatelogId, id);
List<AttrGroupEntity> groupEntityList = attrGroupService.list(wrapperAttrGroup);
if (CollUtil.isNotEmpty(groupEntityList)) {
throw new MallException("请先删除关联属性分组信息");
}
// 3、销售属性/规格参数
LambdaQueryWrapper<AttrEntity> wrapperAttr = new LambdaQueryWrapper<AttrEntity>()
.eq(AttrEntity::getCatelogId, id);
List<AttrEntity> attrEntityList = attrService.list(wrapperAttr);
if (CollUtil.isNotEmpty(attrEntityList)) {
throw new MallException("请先删除关联销售属性/规格参数信息");
}
}
categoryDao.deleteBatchIds(asList); categoryDao.deleteBatchIds(asList);
//删除后清除缓存
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
} }
@Override @Override
@ -66,6 +132,9 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
//更新关联表 //更新关联表
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName()); categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
//删除缓存
stringRedisTemplate.delete(Arrays.asList(CATALOG_BEFORE,CATALOG_AFTER));
} }
@Override @Override
@ -77,41 +146,55 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
@Override @Override
public Map<String, List<Catelog2Vo>> getCatalogJson() { public Map<String, List<Catelog2Vo>> getCatalogJson() {
//先查缓存
String catalogJSON = stringRedisTemplate.opsForValue().get(CATALOG_BEFORE);
if (StringUtils.isEmpty(catalogJSON)) {
//缓存没有查数据库并且放入
Map<String, List<Catelog2Vo>> catalogJsonFormDb = this.getCatalogJsonFormDb();
String jsonString = JSON.toJSONString(catalogJsonFormDb);
stringRedisTemplate.opsForValue().set(CATALOG_BEFORE, jsonString);
return catalogJsonFormDb;
} else {
return JSON.parseObject(catalogJSON, new TypeReference<Map<String, List<Catelog2Vo>>>() {
});
}
}
//可优化
private Map<String, List<Catelog2Vo>> getCatalogJsonFormDb() {
//查出所有1级分类 //查出所有1级分类
List<CategoryEntity> level1Categorys = getLevel1Categorys(); List<CategoryEntity> level1Categorys = getLevel1Categorys();
//封装数据 //封装数据
return level1Categorys.stream().collect(Collectors.toMap( return level1Categorys.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {
k -> k.getCatId().toString(), //每一个的一级分类,查到这个一级分类的二级分类
v -> { List<CategoryEntity> categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, v.getCatId()));
//每一个的一级分类,查到这个一级分类的二级分类
List<CategoryEntity> categoryEntities = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, v.getCatId())); //封装上面的结果
List<Catelog2Vo> catelog2Vos = null;
//封装上面的结果 if (categoryEntities != null) {
List<Catelog2Vo> catelog2Vos = null; catelog2Vos = categoryEntities.stream().map(l2 -> {
if (categoryEntities != null) { Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName());
catelog2Vos = categoryEntities.stream().map(l2 -> {
Catelog2Vo catelog2Vo = new Catelog2Vo(v.getCatId().toString(), null, l2.getCatId().toString(), l2.getName()); // 找当前二级分类的三级分类封装成vo
List<CategoryEntity> level3Catelog = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, l2.getCatId()));
// 找当前二级分类的三级分类封装成vo if (level3Catelog != null) {
List<CategoryEntity> level3Catelog = super.baseMapper.selectList(new LambdaQueryWrapper<CategoryEntity>().eq(CategoryEntity::getParentCid, l2.getCatId()));
if (level3Catelog != null) { List<Catelog2Vo.Catelog3Vo> catelog3Vos = level3Catelog.stream().map(l3 -> {
//封装成指定格式
List<Catelog2Vo.Catelog3Vo> catelog3Vos = level3Catelog.stream().map(l3 -> { return new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
//封装成指定格式
return new Catelog2Vo.Catelog3Vo(l2.getCatId().toString(), l3.getCatId().toString(), l3.getName());
}).collect(Collectors.toList());
catelog2Vo.setCatalog3List(catelog3Vos);
}
return catelog2Vo;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
catelog2Vo.setCatalog3List(catelog3Vos);
} }
return catelog2Vos; return catelog2Vo;
} }).collect(Collectors.toList());
)); }
return catelog2Vos;
}));
} }
//225,25,2 //225,25,2
@ -139,10 +222,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity
//-----------peek和map区别---------------// //-----------peek和map区别---------------//
//map有返回值peek没有返回值 //map有返回值peek没有返回值
return all.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), root.getCatId())) return all.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), root.getCatId())).peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all))).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))).collect(Collectors.toList());
.peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all)))
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
.collect(Collectors.toList());
} }

@ -619,7 +619,7 @@
<script type="text/javascript" src="index/js/header.js"></script> <script type="text/javascript" src="index/js/header.js"></script>
<script type="text/javascript" src="index/js/secend.js"></script> <script type="text/javascript" src="index/js/secend.js"></script>
<script type="text/javascript" src="index/js/zz.js"></script> <script type="text/javascript" src="index/js/zz.js"></script>
<script type="text/javascript" src="index/jsindex.js"></script> <script type="text/javascript" src="index/js/index.js"></script>
<script type="text/javascript" src="index/js/left,top.js"></script> <script type="text/javascript" src="index/js/left,top.js"></script>
<script type="text/javascript" src="index/js/catalogLoader.js"></script> <script type="text/javascript" src="index/js/catalogLoader.js"></script>
</html> </html>

Loading…
Cancel
Save