级联关系——商品管理,Redis
此次主要记录给商品管理新加的三级联动的下拉框,写微服务接口。也能实现APP的三级菜单。主要分两大块:查询数据库对Redis进行更新,根据列表级别和上级的code来查Redis
需再明确的知识点
-
PO 与 VO
Persistent object 持久对象,与数据库表相映射的Java对象。Value object,值对象。通常用于业务层之间的数据传递。
PO用在数据层,VO用在业务逻辑层和表示层。
-
GET 和 POST
GET - 基本的URL请求,一般用于执行查询操作。
- 缺:URL有长度限制,且明文暴露 优:速度快- SpringMVC中的两种get方法:
//(1)RequestParam - 可省略注解,最常用的一般方法url: ? & @RequestMapping(value = "/find/linkage", method = RequestMethod.GET) public ApiResponse<List<JcBcLinkageVo>> findLinkageMenu(@RequestParam(value="level",required=false,defaultValue="0")int level,@RequestParam("code")String code){}//required=false代表非必填参数 //(2)PathVariable @RequestMapping(value = "/find/linkage/{level}/{code}", method = RequestMethod.GET) public ApiResponse<List<JcBcLinkageVo>> findLinkageMenu(@PathVariable("level")int level,@PathVariable("code")String code){}
POST - 把数据放到body里面,一般配合from表单使用
- 慢的原因:
<1>(TCP三次握手)
post多(服务器返回100 - continue,客户端开始发送数据)
(服务器返回200 - ok)
<2> get会缓存数据
<3> post不能进行管道化传输 -
CollectionUtils集合操作类
CollectionUtils.isEmpty(null); //true CollectionUtils.isEmpty(new ArrayList()); //ture CollectionUtils.isEmpty({a,b}); //false //CollectionUtils.isNotEmpty()相反 /* *集合a: {1,2,3,3,4,5} *集合b: {3,4,4,5,6,7} */ CollectionUtils.union(a, b)(并集);// {1,2,3,3,4,4,5,6,7} CollectionUtils.intersection(a, b)(交集);// {3,4,5} CollectionUtils.disjunction(a, b)(交集的补集);// {1,2,3,4,6,7} CollectionUtils.disjunction(b, a)(交集的补集);// {1,2,3,4,6,7} CollectionUtils.subtract(a, b)(A与B的差);// {1,2,3} CollectionUtils.subtract(b, a)(B与A的差);// {4,6,7}
-
- MyBatis中的like语句
<select id="findLinkageSon" resultMap="BaseResultMap" parameterType="java.lang.String"> SELECT <include refid="Base_Column_List" /> FROM jc_bc_linkage l WHERE l.`code` LIKE CONCAT(#{param},'%') AND l.`status`='1'; </select>
String[] strs=str.split(",");
String.trim() 去首尾空格
-
-
清空弹框中的历史
-
级联下拉框
$("#id").val("<option value="">请选择</option>");
-
表格tbody
function removeTbody(){ //全清空 $("#tableid").html(""); //清空选中 var table = document.getElementById('tableid'); var tbodies= table.getElementsByTagName("tbody"); for(i=0;i<tbodies.length;i++){ if(tbodies[i].id=='tid'){ table.removeChild(tbodies[i]); } } }
弹框调用
alertTip({ type: 'confirm', msg: '修改加价率,加价率价和线上价会随着变化,确定要修改吗?', confirmCallBack: function(){ changeRate(rate,totalId,sellingPrice,claimLocalPrice,serviceRate); } });
-
Redis更新
ConfigApi.java
/**
* 商品分类三级列表缓存更新
* @author QJJ
* @return
*/
@RequestMapping(value="cache/update/linkage",method = RequestMethod.GET)
public ApiResponse<String> redisLinkageUpdate(){
configService.updatelinkageRedis();
return new ApiResponse<String>("更新linkage成功");
}
ConfigService.java
/**
* 级联配置商品关系列表缓存信息更新
* @author QJJ
* @date 2018年10月9日 下午3:40:23
*/
@SuppressWarnings("null")
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public void updatelinkageRedis(){
log.debug("更新级联缓存开始");
//清除缓存
configReidsUtil.removeLinkages();
List<JcBcLinkage> linkageList = jcBcLinkageDao.findFirstGrand();//一级列表
if(CollectionUtils.isEmpty(linkageList)){
return;
}
configReidsUtil.saveLinkage(1,null,linkageList);
List<JcBcLinkage> sonList = null;
List<JcBcLinkage> childList = new ArrayList<>();
List<JcBcLinkage> grandSonList = null;
Map<String,List<JcBcLinkage>> childMap = new HashMap<>();
Map<String,List<JcBcLinkage>> grandSonMap = new HashMap<>();
for(JcBcLinkage linkage:linkageList) {
sonList = jcBcLinkageDao.findLinkageSon(linkage.getCode());
if(CollectionUtils.isEmpty(sonList)) {
break;
}
for(JcBcLinkage son:sonList) {
int level = son.getLevel();
switch(level) {
case 1:
break;
case 2:
if(null == childMap.get(son.getParentCode())) {
childList = new ArrayList<>();
childList.add(son);
childMap.put(son.getParentCode(), childList);
}else {
childMap.get(son.getParentCode()).add(son);
}
break;
case 3:
if(null == grandSonMap.get(son.getParentCode())) {
grandSonList = new ArrayList<>();
grandSonList.add(son);
grandSonMap.put(son.getParentCode(), grandSonList);
}else {
grandSonMap.get(son.getParentCode()).add(son);
}
break;
default:
break;
}
}
}
if(!childMap.isEmpty()) {
for(String code:childMap.keySet()) {
configReidsUtil.saveLinkage(2, code, childMap.get(code));
}
}
if(!grandSonMap.isEmpty()) {
for(String code:grandSonMap.keySet()) {
configReidsUtil.saveLinkage(3, code, grandSonMap.get(code));
}
}
log.debug("一级二级增加个数:{}",linkageList.size());
log.debug("二级三级增加个数:{}",grandSonMap.size());
log.debug("更新缓存结束");
}
ConfigReidsUtil.java
/**
* 清除级联缓存
*/
public void removeLinkages() {
super.removePattern(LINKAGE1);
super.removePattern(LINKAGE2);
}
/**
* 将对应linkagelist存入缓存
* @author QJJ
* @param level
* @param code
* @param linkageList
*/
public void saveLinkage(int level,String code,List<JcBcLinkage> linkageList) {
switch(level) {
case 1:
super.set(LINKAGE1, JacksonUtil.toJSon(linkageList));
break;
case 2:
super.hmSet(LINKAGE2, code, JacksonUtil.toJSon(linkageList));
break;
case 3:
super.hmSet(LINKAGE3, code, JacksonUtil.toJSon(linkageList));
break;
default:
break;
}
}
Redis查找
ConfigApi.java
/**
* 根据级别和内容查找列表
* @author QJJ
* @param level
* @param code
* @return ApiResponse<List<JcBcLinkageVo>>
*/
@RequestMapping(value = "/find/linkage", method = RequestMethod.GET)
public ApiResponse<List<JcBcLinkageVo>> findLinkageMenu(int level,String code){
List<JcBcLinkageVo> linkageList = configService.findLinkages(level, code);
return new ApiResponse<List<JcBcLinkageVo>>(linkageList);
}
ConfigService.java
/**
* 级联配置寻找对应list
* @Title: List<JcBcLinkageVo> findLinkages
* @author QJJ
* @date 2018年9月20日 下午3:40:23
*/
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public List<JcBcLinkageVo> findLinkages(int level,String code){
log.debug("寻找级联关系开始");
List<JcBcLinkageVo> linkagelist = configReidsUtil.findLinkageList(level,code);
log.debug("寻找级联关系结束");
return linkagelist;
}
ConfigReidsUtil.java
/**
* 寻找linkageList
* @author QJJ
* @param key
* @return
*/
@SuppressWarnings({ "null", "unchecked" })
public List<JcBcLinkageVo> findLinkageList(int level,String key){
List<JcBcLinkageVo> childlist = null;
Object obj = null;
switch(level){
case 1:
obj= super.get(LINKAGE1);
if(obj != null) {
childlist = JacksonUtil.readValue((String)obj, new TypeReference<List<JcBcLinkageVo>>() {});
}
break;
case 2:
obj = redis.hmGet(LINKAGE2,key);
if(obj != null) {
childlist = JacksonUtil.readValue((String)obj, new TypeReference<List<JcBcLinkageVo>>() {});
}
break;
case 3:
obj= redis.hmGet(LINKAGE3,key);
if(obj != null) {
childlist = JacksonUtil.readValue((String)obj, new TypeReference<List<JcBcLinkageVo>>() {});
}
break;
default:
break;
}
return childlist;
}
JcBcLinkageDao.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">
<!-- ============================================================== -->
<!-- ================可直接使用Base配置文件中定义的节点!================ -->
<!-- ============================================================== -->
<mapper namespace="com.jiaanpei.common.config.dao.JcBcLinkageDao">
<!-- 请在下方添加自定义配置-->
<select id="findFirstGrand" resultMap="BaseResultMap">
SELECT <include refid="Base_Column_List" />
FROM jc_bc_linkage l WHERE l.`level`='1' AND l.`status`='1';
</select>
<select id="findLinkageSon" resultMap="BaseResultMap" parameterType="java.lang.String">
SELECT <include refid="Base_Column_List" />
FROM jc_bc_linkage l WHERE l.`code` LIKE CONCAT(#{param},'%') AND l.`status`='1';
</select>
</mapper>
JcBcLinkageDao.java
package com.jiaanpei.common.config.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.jiaanpei.common.config.po.JcBcLinkage;
import com.jiaanpei.common.config.vo.JcBcLinkageVo;
import ins.framework.mybatis.MybatisBaseDao;
/**
*
* 表jc_bc_linkage对应的基于MyBatis实现的Dao接口<br/>
* 在其中添加自定义方法
*
*/
@Mapper
public interface JcBcLinkageDao extends MybatisBaseDao<JcBcLinkage, String> {
/**
* 取出一级列表
* @param id
* @param limit
* @return
*/
public List<JcBcLinkage> findFirstGrand();
/**
* 按一级code找出对应的一级二级三级列表
* @param code
* @return
*/
public List<JcBcLinkage> findLinkageSon(String code);
}
组装三级业务对象
/**
* 组装三级对象
* @Title: List<JcBcLinkageVo> findLinkages
* @author QJJ
* @date 2018年10月9日 下午3:40:23
*/
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public List<JcBcLinkageVo> findLinkages(String findType){
log.debug("寻找级联关系开始");
Map<String,List<JcBcLinkageVo>> map1 = configReidsUtil.findLinkageMap();
List<JcBcLinkageVo> linkagelist = null;//一级
List<JcBcLinkageVo> childrenlist = null;//二级
List<JcBcLinkageVo> grandsons = null;//三级
for(String key:map1.keySet()) {//一级key
childrenlist = map1.get(key);
for(JcBcLinkageVo children:childrenlist) {//循环二级对象去找三级
grandsons = configReidsUtil.findLinkageMap(children.getCode()+"-"+children.getName());
children.setChildList(grandsons);
}
if("2".equals(findType)) {
return childrenlist;
}
JcBcLinkageVo linkage = new JcBcLinkageVo();
String[] linkageKeys = key.split("-");
linkage.setCode(linkageKeys[0]);
linkage.setName(linkageKeys[1]);
linkage.setChildList(childrenlist);
linkagelist.add(linkage);
}
log.debug("寻找级联关系结束");
return null;
}