spring Cache + Redis 开发数据字典以及自定义标签


多读多写多记录,多学多练多思考。---------- Banana.Banuit Gang(香柚帮)


记录下来供自己参考学习

一、数据库表结构

1、  分类表:dict_type

       

2、  子项表:dict_entry

 

二、页面维护功能示意图:

1、  分类管理 点击子项管理进入子项管理页面

    

2、子项管理

    

三、数据字典添加到缓存:

数据字典为了读取效率高效,减少与数据库的交互,通常会把数据字典所有数据添加到缓存当中,如果是一台服务器部署,只需放到本机中就可以,如果需要部署到多台服务器分布式部署的话需要把数据字典同步到Redis服务器中。

1、  springboot 在dictTypeService中把数据字典放到本机缓存中

对数据字典进行增删改查时需要调用refreshDictCache()方法来刷新缓存,保证缓存中数据为最新数据

2、  如果使用springboot + Redis做缓存的使用的方法,在dictTypeService中把数据字典放到Redis服务器中

@Cacheable(value="dictEntry", key="T(String).valueOf('dictEntryMap')")

使用此注解调用此方法时,系统会先从Redis服务器获取数据字典,如果取不到数据,系统会再去数据库读取。

@CacheEvict(value="dictEntry", key="T(String).valueOf('dictTypeNameMap')")

方法使用此注解,对数据字典进行增删改查时,系统会自动同步到Redis服务器,保证数据库数据与redis数据保持一致。

三、把数据字典做成自定义标签

1、  创建辅助类(自定义标签调用)

package com.hydwltech.iems.epum.common.utils;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.hydwltech.iems.epum.entity.dict.DictEntryOV;
import com.hydwltech.iems.epum.service.dict.DictTypeService;

/**
 * 数据字典工具类
 **/
public class DictUtil {
    private static DictTypeService getDictTypeService() {
        return SpringWebContextUtil.getApplicationContext().getBean(DictTypeService.class);
    }

    /**
     * 根据类型编码获取子项列表
     *
     * @param dictTypeCode 类型编码
     * @return List<{@link DictEntryOV}}> 子项数据对象
     */
    @SuppressWarnings("unchecked")
    public static List<DictEntryOV> getDictEntryList(String dictTypeCode) {
        return (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
    }

    /**
     * 根据类型编码和子项编码获得子项名称
     *
     * @param dictTypeCode  类型编码
     * @param dictEntryCode 子项编码
     * @return String 子项名称
     */
    public static String getDictEntryName(String dictTypeCode, String dictEntryCode) {
        if (StringUtils.isBlank(dictTypeCode)) {
            return null;
        }
        if (StringUtils.isBlank(dictEntryCode)) {
            return null;
        }
        List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
        String entryCode = null;
        if (isInteger(dictEntryCode)) {
            List<String> nameMapKeys = new ArrayList<String>();
            for (DictEntryOV dictOv : ovlist) {
                String[] names = dictOv.getDictEntryCode().split(",");
                boolean namesIsInt = true;
                for (int i = 0; i < names.length; i++) {
                    if (!isInteger(names[i])) {
                        namesIsInt = false;
                        break;
                    }
                }
                if (namesIsInt) {
                    nameMapKeys.add(dictOv.getDictEntryCode());
                }
            }

            for (String parm : nameMapKeys) {
                if (parm.split(",").length == 1) {
                    int parm1 = Integer.parseInt(parm.split(",")[0]);
                    if (Integer.parseInt(dictEntryCode) == parm1) {
                        entryCode = parm;
                    }
                } else if (parm.split(",").length == 2) {
                    int parm1 = Integer.parseInt(parm.split(",")[0]);
                    int parm2 = Integer.parseInt(parm.split(",")[1]);
                    if (Integer.parseInt(dictEntryCode) >= parm1 && Integer.parseInt(dictEntryCode) <= parm2) {
                        entryCode = parm;
                    }
                }
            }
        } else {
            entryCode = dictEntryCode;
        }

        String entryName = null;
        if (StringUtils.isNotBlank(entryCode)) {
            for (DictEntryOV dictEntryOV : ovlist) {
                if (entryCode.equals(dictEntryOV.getDictEntryCode())) {
                    entryName = dictEntryOV.getDictEntryName();
                }
            }
        }

        return entryName;
    }

    /**
     * 根据类型编码和子项编码获得子项对象
     *
     * @param dictTypeCode  类型编码
     * @param dictEntryCode 子项编码
     * @return DictEntryOV 子项名称
     */
    public static DictEntryOV getDictEntry(String dictTypeCode, String dictEntryCode) {
        if (StringUtils.isBlank(dictTypeCode)) {
            return null;
        }
        if (StringUtils.isBlank(dictEntryCode)) {
            return null;
        }
        List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
        DictEntryOV entryOv = null;
        for (DictEntryOV dictEntryOV : ovlist) {
            if (dictEntryCode.equals(dictEntryOV.getDictEntryCode())) {
                entryOv = dictEntryOV;
            }
        }
        return entryOv;
    }

    /**
     * 根据类型编码和子项编码获得子项名称
     *
     * @param dictTypeCodeAndEntryCode 类型编码和子项编码合成字符串两个变量已逗号隔开
     * @return String 子项名称
     */
    public static String getDictEntryNameByCodes(String dictTypeCodeAndEntryCode) {
        if (StringUtils.isBlank(dictTypeCodeAndEntryCode)) {
            return null;
        }
        String[] params = dictTypeCodeAndEntryCode.split(",");
        String dictTypeCode = params[0];
        String dictEntryCode = params[1];
        List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
        String entryName = null;
        for (DictEntryOV dictEntryOV : ovlist) {
            if (dictEntryCode.equals(dictEntryOV.getDictEntryCode())) {
                entryName = dictEntryOV.getDictEntryName();
            }
        }
        return entryName;
    }

    /**
     * 根据类型编码获得类型名称
     *
     * @param dictTypeCode 类型编码
     * @return String 子项名称
     */
    public static String getDictTypeName(String dictTypeCode) {
        if (StringUtils.isBlank(dictTypeCode)) {
            return null;
        }
        String type = (String) getDictTypeService().getDictTypeNameMap().get(dictTypeCode);
        return type;

    }

    /**
     * 根据类型编码和子项名称获得子项类型编码
     *
     * @param dictTypeCode  类型编码
     * @param dictEntryName 子项名称
     * @return String 子项编码
     */
    public static String getDictEntryCodeByEntryName(String dictTypeCode, String dictEntryName) {
        if (StringUtils.isBlank(dictTypeCode)) {
            return null;
        }
        if (StringUtils.isBlank(dictEntryName)) {
            return null;
        }
        List<DictEntryOV> ovlist = (List<DictEntryOV>) getDictTypeService().getDictEntryMap().get(dictTypeCode);
        String entryCode = null;
        for (DictEntryOV ov : ovlist) {
            if (dictEntryName.equals(ov.getDictEntryName())) {
                entryCode = ov.getDictEntryCode();
            }
        }
        return entryCode;
    }

    /** 验证是否是整数 */
    private static boolean isInteger(String param) {
        try {
            Integer.valueOf(param);
            return true;
        } catch (Exception e) {
            // TODO: handle exception
        }
        return false;
    }
}

2、  自定义JSTL标签类

   (1)需要定义几个标签,就写几个独立的标签类

  (2)定义标签类,在页面输出下拉菜单数据

package com.hydwltech.iems.epum.common.utils.tag;

import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import com.hydwltech.iems.epum.common.utils.DictUtil;
import com.hydwltech.iems.epum.entity.dict.DictEntryOV;

public class ValueDictEntryListUtil extends TagSupport{

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private String var;

    @Override
    public int doStartTag() throws JspException {
        try {
            StringBuffer strBuffer = new StringBuffer();
            List<DictEntryOV> ovList = DictUtil.getDictEntryList(var);
            for (int i = 0; i < ovList.size(); i++) {
                strBuffer.append("<li>");
                strBuffer.append("<a href=\"###\" value="+ovList.get(i).getDictEntryCode()+">" + ovList.get(i).getDictEntryName() + "</a>");
                strBuffer.append("</li>");
            }
            pageContext.getOut().print(strBuffer.toString());
        } catch (Exception e) {
            // TODO: handle exception
        }
        return EVAL_BODY_INCLUDE;
    }


    public String getVar() {
        return var;
    }

    public void setVar(String var) {
        this.var = var;
    }
}

(3)、创建tld文件

      在WEB-INF下创建tld文件 dict.tld

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
    "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.0</tlib-version><!-- 标签库版本 -->
    <jsp-version>1.2</jsp-version>  <!-- 标签库要求的JSP规范版本 -->
    <short-name>dict</short-name>   <!-- JSP页面编写工具可以用来创建助记名的可选名字 -->
    <!--
         为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写,如这里的/gacl ,
         在Jsp页面中引用标签库时,需要通过uri找到标签库
         在Jsp页面中就要这样引入标签库:
         <%@taglib uri="/security/encrypt" prefix="encrypt"%>
     -->
    <!-- <uri>/security/encrypt</uri> -->
    <tag>
        <name>entry</name>
        <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictEntryNameUtil</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>typeCode</name>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>entryCode</name>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>type</name>
        <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictTypeNameUtil</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>var</name>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>select</name>
        <tag-class>com.hydwltech.iems.epum.common.utils.tag.ValueDictEntryListUtil</tag-class>
        <body-content>JSP</body-content>
        <attribute>
            <name>var</name>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

(4)、JSP页面调用标签

      A、导入自定义标签

       <%@ taglib prefix="dict" uri="/WEB-INF/tag/dict.tld"%>

      

    B、下拉菜单调用此标签

       <dict:select var="equipEablePatrol"/>

 

效果如下图:

除了下拉菜单标签,还可以根据自己的需求开发其他自定义标签。

四、相关技术链接

      关于自定义标签转自:https://blog.csdn.net/bilahepan/article/details/54801540

      关于Springboot  + cacheable + Redis转自:https://blog.csdn.net/moshowgame/article/details/80792774

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值