三级联动下拉框

级联关系——商品管理,Redis

​ 此次主要记录给商品管理新加的三级联动的下拉框,写微服务接口。也能实现APP的三级菜单。主要分两大块:查询数据库对Redis进行更新,根据列表级别和上级的code来查Redis

需再明确的知识点

  1. PO 与 VO

    Persistent object 持久对象,与数据库表相映射的Java对象。Value object,值对象。通常用于业务层之间的数据传递。

    PO用在数据层,VO用在业务逻辑层和表示层。

  2. 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不能进行管道化传输

  3. 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}
    
    
      1. 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>
      
    1. String[] strs=str.split(",");

    String.trim() 去首尾空格

  4. 清空弹框中的历史

    1. 级联下拉框

      $("#id").val("<option value="">请选择</option>");
      
    2. 表格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]);
              }
          }
      } 
      
    3. 弹框调用

    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;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355