springboot+redis+切面实现数据字典和自动设置用户信息功能解放双手

背景:

       我们数据库为了减少存储容量和数据查询传输量以及增大查询效率,一般都会把字段进行编码而不是存中文,所以有时候字段值有可能是0 ==未处理,1 == 已处理。 但是,展示到前端需要将 值翻译成中文,如果人工来做会很麻烦,解放双手将此类工作交给程序来解决.

实现目标:

源码:自定义注解:DataDict,用于bo对象类,需要翻译的属性

package com.qboa.common.annotation.dict;

import java.lang.annotation.*;

/**
 * 说明:数据字典处理类
 * Created by luojie on 2019/05/29.
 */
//@DataDict(  dict="patType", source = "patType" )
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataDict {

    /**
     * 方法描述 描述标准编码 或是用户字段(对应UserBo)
     * 与user配合使用,需要取的信息字段
     * 如:要去age 则配置age 要取 userName 则配置 userName
     *
     * @return
     */
    String dict() default "";

    /**
     * 翻译类型 "0" 标准代码  "1"用户
     *
     * @return
     */
    String busi() default "0";

    /**
     * 方法描述,可使用占位符获取参数:{{source}}
     * 主要标准编码之来源,
     * 查询用户信息时存储用户userId 的字段名称
     */
    String source() default "";

    /**
     * 对source 值是否需要对行转列进行拆分处理{{","}}
     * 需要对source值按逗号进行拆分后翻译,默认拆分转换
     * 若是{{$}}则按$进行拆分
     * 默认不处理
     * 如:
     * "proMode": "1,2",
     * "proModeName": "出售,结算",
     *
     * @return
     */
    String transferLineColumn() default "";

    /**
     * 方法描述 描述标准编码组
     * 翻译该字段需要哪些标准码
     *
     * @return
     */
    String[] dictArr() default {};

    /**
     * 方法描述 区分字段,先决条件
     * 决定取哪个标准编码
     *
     * @return
     */
    String differ() default "";

    /**
     * 方法描述 区分字段,先决条件比较值
     * 决定取哪个标准编码比较值
     * 满足条件获取下标 从dictArr 中取下标的标准代码
     *
     * @return
     */
    String[] differValues() default {};


}

自定义注解: 

DataDictClass  用来标注返回对象集合需要翻译的方法,本功能目前只支持bean对象的属性翻译

package com.zddts.common.annotation.dict;

import java.lang.annotation.*;

/**
 * 说明:
 * Created by luojie on 2019/05/29.
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataDictClass {

}

切面处理: DataDictAspect

package com.qboa.oa.aop;

import com.alibaba.fastjson.JSON;
import com.qboa.common.annotation.dict.DataDict;
import com.qboa.common.annotation.dict.DataDictClass;
import com.qboa.common.bo.admin.UserBo;
import com.qboa.common.bo.pubapp.puCode.PuCodeBo;
import com.qboa.common.contants.ReidsConstants;
import com.qboa.common.utils.BeanUtils;
import com.qboa.oa.client.PubAppClient;
import com.qboa.oa.util.UserUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 说明:数据字典切面类
 * Created by luojie on 2019/05/29.
 */
@Aspect
@Component
public class DataDictAspect {

    @Autowired
    PubAppClient pubappClient;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private UserUtil userUtil;


    /**
     * 非基本类型在 CLASS 中的定义
     */
    private static final String FILED_NAME_TYPE = "TYPE";

    private Map<String, String> dictInfoMap = new ConcurrentHashMap<>();

    @Pointcut("@annotation(dataDictClass)")
    public void doDataDictClass(DataDictClass dataDictClass) {
    }

    @Around("@annotation(dataDictClass)")
    public Object translation(final ProceedingJoinPoint pjp, DataDictClass dataDictClass) throws Throwable {
        Object result = pjp.proceed();
        if (result == null) {
            return result;
        }
        Object obj;
        if (result instanceof List || result instanceof ArrayList) {

            List olist = ((List) result);
            if (olist.size() == 0) {
                return result;
            }
            obj = olist.get(0);
        } else if (result instanceof Page) {//支持Page类的数据字典转换
            List olist = ((Page) result).getContent();
            if (olist.size() == 0) {
                return result;
            }
            obj = olist.get(0);
        } else {
            obj = result;
        }
        /**
         * 获取翻译字段配置信息
         */
        Map<String, DataDict> dataDictMap = boDict(obj.getClass());
        if (dataDictMap.size() == 0) {
            return result;
        }

        /**
         * 获取字典信息
         */
        this.getPCodeInfo();
        /**
         * 开始翻译
         */
        if (result instanceof List || result instanceof ArrayList) {
            for (Object o : (List) result) {
                sign(o, dataDictMap, dictInfoMap);
            }
        } else if (result instanceof Page) {//支持Page类
            ((Page) result).forEach(o -> sign(o, dataDictMap, dictInfoMap));
        } else {
            sign(result, dataDictMap, dictInfoMap);
        }
        return result;
    }

    /**
     * 设置数据字典
     */
    public void getPCodeInfo() throws Exception {
        Object codeObj = redisTemplate.opsForValue().get(ReidsConstants.PUCODE_REDIS_ALL);
        List<PuCodeBo> dictInfos;
        //缓存中没有重新从数据库中取
        if (codeObj == null) {
            dictInfos = pubappClient.getAllPuCode();
            redisTemplate.opsForValue().set(ReidsConstants.PUCODE_REDIS_ALL, dictInfos);
        } else {
            dictInfos = (List<PuCodeBo>) codeObj;
        }
        if (dictInfos == null || dictInfos.size() == 0) {
            return;
        }
        //先把字典值转成map
        for (PuCodeBo puCodeBo : dictInfos) {
            dictInfoMap.put(puCodeBo.getCodeType() + puCodeBo.getCodeValue(), puCodeBo.getCodeName());
        }
    }

    /**
     * 获取bo中属性值
     *
     * @param cla
     * @return
     */
    private Map<String, DataDict> boDict(Class cla) {
        Field[] fields = cla.getDeclaredFields();
        Map<String, DataDict> map = new HashMap<String, DataDict>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(DataDict.class)) {
                DataDict dataDict = field.getAnnotation(DataDict.class);
                String fieldName = field.getName();
                map.put(fieldName, dataDict);
            }
        }
        return map;
    }

    /**
     * 单个设置值
     *
     * @param obj
     * @param dataDictMap 注解字段
     * @param dictInfoMap
     */
    public void sign(Object obj, Map<String, DataDict> dataDictMap, Map<String, String> dictInfoMap) {

        for (Map.Entry<String, DataDict> entry : dataDictMap.entrySet()) {
            String fileName = entry.getKey();
            DataDict dataDict = entry.getValue();
            String busi = StringUtils.isBlank(dataDict.busi()) ? "0" : dataDict.busi();
            //翻译类型
            if ("0".equals(busi)) {
                this.setPCode(obj, dataDict, fileName, dictInfoMap);
            } else if ("1".equals(busi)) {//翻译用户字段
                this.setUserInfo(obj, dataDict, fileName);
            }

        }


    }

    /**
     * 设置标准代码--字典
     *
     * @param obj
     * @param dataDict    属性的注解字段配置
     * @param fileName    需要赋值的字段
     * @param dictInfoMap 字典信息数据
     * @throws Exception
     */
    public void setPCode(Object obj, DataDict dataDict, String fileName, Map<String, String> dictInfoMap) {
        if (dictInfoMap == null || dictInfoMap.size() == 0) {
            return;
        }
        String dict = dataDict.dict();
        if (StringUtils.isBlank(dict)) {
            String[] dictArr = dataDict.dictArr();//多个字典组 长度与differValues必须一致
            String differ = dataDict.differ();   // 字典  选择条件字段 作区分的字段
            String[] differValuesArr = dataDict.differValues();//differ 对应值的枚举值  匹配上选对应下标的dict字典来取值
            try {
                //作区分字段的值
                String differValue = (String) BeanUtils.getBeanFieldValue(obj.getClass(), obj, differ);
                if (StringUtils.isBlank(differValue)) {
                    //值无数据不比较
                    return;
                }
                for (int i = 0; i < differValuesArr.length; i++) {
                    if (differValue.equals(differValuesArr[i])) {
                        dict = dictArr[i];
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //未匹配上字典不设置
        if (StringUtils.isBlank(dict)) {
            return;
        }
        String source = dataDict.source();//需要翻译的字段
        String transferLineColumn = dataDict.transferLineColumn();//拆分符号 有则按照拆分符号拆分翻译
        try {
            //获取源编码值
            String sourceValue = (String) BeanUtils.getBeanFieldValue(obj.getClass(), obj, source);
            String dictCodeName = null; //字典值 翻译后的值
            //新增对例如1,2,3 多个值要标准码转换进行转换"proMode": "1,2",         "proModeName": "出售,结算",
            if (StringUtils.isNotBlank(transferLineColumn)) {
                if (StringUtils.isNotBlank(sourceValue) && sourceValue.indexOf(transferLineColumn) > 0) {
                    String[] s = sourceValue.split(transferLineColumn);
                    for (int i = 0; i < s.length; i++) {
                        String a = s[i];
                        if (i == 0) {
                            dictCodeName = dictInfoMap.get(dict + a);
                        } else {
                            dictCodeName = dictCodeName + transferLineColumn + dictInfoMap.get(dict + a);
                        }
                    }
                } else {
                    dictCodeName = dictInfoMap.get(dict + sourceValue);
                }
            } else {
                dictCodeName = dictInfoMap.get(dict + sourceValue);
            }
            //设置值
            BeanUtils.setBeanField(obj.getClass(), obj, fileName, dictCodeName);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 设置用户信息
     *
     * @param obj
     * @param dataDict 属性注解字段配置
     * @param fileName 需要赋值的字段
     * @throws Exception
     */
    public void setUserInfo(Object obj, DataDict dataDict, String fileName) {
        String source = dataDict.source(); //存储用户userId 的字段名称
        String dict = dataDict.dict();//获取用户目标信息的字段
        if (StringUtils.isBlank(dict)) {
            return;
        }
        try {
            Object userIdobj = BeanUtils.getBeanFieldValue(obj.getClass(), obj, source);
            if (userIdobj == null) {
                return;
            }
            String userIdstr = String.valueOf(userIdobj);
            if ("".equals(userIdstr)) {
                return;
            }
            Long userId = Long.valueOf(userIdstr);
            //查询用户信息 根据自己配置是数据库还是redis
            UserBo user = userUtil.getUserBoInRedis(userId);
            if (user == null) {
                return;
            }
            //todo 目前支持字符串类型 数值类型,不支持对象 类型 和时间类型 目标和源 的类型必须要一致
            Object fromValue = BeanUtils.getBeanFieldValue(user.getClass(), user, dict);
            //设置值
            BeanUtils.setBeanField(obj.getClass(), obj, fileName, fromValue);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }


    }

    /**
     * json处理 todo
     *
     * @param returnJsonResult
     * @param returnType
     * @return
     */
    private Object getJsonToResultObject(String returnJsonResult, Class returnType) {
        // 对象复原
        if (StringUtils.isNotBlank(returnJsonResult)) {
            // 基本类型则直接返回封装类型则对象转换
            if (returnType.isPrimitive()) {
                return returnJsonResult;
            } else {
                try {
                    if ((returnType.getField(FILED_NAME_TYPE)
                            .getClass()).isPrimitive()) {
                        return returnJsonResult;
                    }
                } catch (Exception e) {
                    return JSON.parseObject(returnJsonResult, returnType);
                }
            }
        }
        return null;
    }


}

工具类:主要用了反射机制

package com.zddts.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;

public class BeanUtils {

    /**
     * 方法说明:将List<Map>转换为List<Bean>
     *
     * @param mapList
     * @param cls
     * @return
     * @throws Exception
     */
    public static List<Object> mapListToBeanList(
            List<Map<String, Object>> mapList, Class<?> cls) throws Exception {
        if (mapList == null || mapList.size() == 0) {
            return null;
        }
        List<Object> beanList = new ArrayList<Object>();
        Object bean = null;
        for (Map<String, Object> map : mapList) {
            bean = mapToBean(map, cls);
            if (bean == null) {
                continue;
            }
            beanList.add(bean);
        }
        return beanList;
    }

    /**
     * 设置bean 属性值,没有下划线的
     *
     * @param map
     * @param cls
     * @return
     * @throws Exception
     */
    public static Object mapToBeanNL(Map<String, Object> map, Class<?> cls) throws Exception {
        if (map == null || map.size() == 0) {
            return null;
        }
        Object obj = cls.newInstance();
        for (Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value == null) {
                continue;
            }
            // 判断字段是否存在
            String fieldName = key;
            Field field = getBeanField(cls, fieldName);
            if (field == null) {
                continue;
            }
            // 判断字段的set方法是否存在
            String setMethodName = StringUtils.pareSetName(fieldName);
            Method method = getBeanMethod(cls, setMethodName, field.getType());
            if (method == null) {
                continue;
            }

            String fieldType = field.getType().getSimpleName();
            if ("String".equals(fieldType)) {
                method.invoke(obj, value.toString());
            } else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
                method.invoke(obj, Long.valueOf(value.toString()));
            } else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
                method.invoke(obj, value.toString());
            } else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
                method.invoke(obj, Double.valueOf(value.toString()));
            } else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
                method.invoke(obj, Float.valueOf(value.toString()));
            } else if ("boolean".equals(fieldType) || "Boolean".equals(fieldType)) {
                if (value.getClass().equals(Boolean.class)) {
                    method.invoke(obj, (Boolean) value);
                } else {
                    method.invoke(obj, Boolean.valueOf(value.toString()));
                }
            } else if ("Date".equals(fieldType)) {
                if (value != null) {
                    if (value.getClass().equals(Date.class)) {
                        method.invoke(obj, (Date) value);
                    } else {
                        method.invoke(obj, DateUtils.strToDate(value.toString()));
                    }
                }
            }
        }
        return obj;
    }

    /**
     * 设置bean 属性值
     *
     * @param map
     * @param cls
     * @return
     * @throws Exception
     */
    public static Object mapToBean(Map<String, Object> map, Class<?> cls)
            throws Exception {
        if (map == null || map.size() == 0) {
            return null;
        }
        Object obj = cls.newInstance();
        for (Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value == null) {
                continue;
            }
            // 判断字段是否存在
            String fieldName = StringUtils.toUnderLine(key.toLowerCase());
            Field field = getBeanField(cls, fieldName);
            if (field == null) {
                continue;
            }
            // 判断字段的set方法是否存在
            String setMethodName = StringUtils.pareSetName(fieldName);
            Method method = getBeanMethod(cls, setMethodName, field.getType());
            if (method == null) {
                continue;
            }

            String fieldType = field.getType().getSimpleName();
            if ("String".equals(fieldType)) {
                method.invoke(obj, value.toString());
            } else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
                method.invoke(obj, Long.valueOf(value.toString()));
            } else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
                method.invoke(obj, value.toString());
            } else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
                method.invoke(obj, Double.valueOf(value.toString()));
            } else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
                method.invoke(obj, Float.valueOf(value.toString()));
            } else if ("boolean".equals(fieldType)
                    || "Boolean".equals(fieldType)) {
                if (value.getClass().equals(Boolean.class)) {
                    method.invoke(obj, (Boolean) value);
                } else {
                    method.invoke(obj, Boolean.valueOf(value.toString()));
                }
            } else if ("Date".equals(fieldType)) {
                if (value != null) {
                    if (value.getClass().equals(Date.class)) {
                        method.invoke(obj, (Date) value);
                    } else {
                        method.invoke(obj, DateUtils
                                .strToDate(value.toString()));
                    }
                }
            }
        }
        return obj;
    }

    /**
     * 方法说明:将List<Bean>转换为List<Map>
     *
     * @param beanList
     * @return
     * @throws Exception
     */
    public static List<Map<String, Object>> beanListToMapList(
            List<Map<String, Object>> beanList) throws Exception {
        if (beanList == null || beanList.size() == 0) {
            return null;
        }
        List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (Object bean : beanList) {
            map = beanToMap(bean);
            if (map == null || map.size() == 0) {
                continue;
            }
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 设置bean 属性值
     *
     * @param bean
     * @return
     * @throws Exception
     */
    public static Map<String, Object> beanToMap(Object bean) throws Exception {
        if (bean == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Class<?> cls = bean.getClass();
        Field fields[] = cls.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            String fieldType = field.getType().getSimpleName();
            boolean isBooleanType = false;
            if (fieldType.equals("boolean") || fieldType.equals("Boolean")) {
                isBooleanType = true;
            }
            String getMethodName = StringUtils.pareGetName(fieldName,
                    isBooleanType);
            // 判断字段的无参get方法是否存在
            Method method = getBeanMethod(cls, getMethodName, new Class[]{});
            if (method == null) {
                continue;
            }
            Object fieldValue = method.invoke(bean, new Object[]{});
            map.put(StringUtils.toUnderLine(field.getName()).toUpperCase(),
                    fieldValue);
        }
        return map;
    }

    /**
     * 判断该方法是否存在
     *
     * @param methods
     * @param met
     * @return
     */
    public static boolean checkMethod(Method methods[], String met) {
        if (null != methods) {
            for (Method method : methods) {
                if (met.equals(method.getName())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 方法说明:获取bean的指定方法
     * <p>
     * <p>
     * Author: zhenqiangs Create Date: 2016-4-30 下午01:07:12 History: 2016-4-30
     * 下午01:07:12 zhenqiangs Created.
     *
     * @param cls
     * @param methodName
     * @param paramTypes
     * @return
     */
    private static Method getBeanMethod(Class<?> cls, String methodName,
                                        Class<?>... paramTypes) {
        if (cls == null) {
            return null;
        }
        Method setMethod = null;
        try {
            setMethod = cls.getMethod(methodName, paramTypes);
        } catch (Exception e) {

        }
        return setMethod;
    }

    /**
     * 方法说明:获取bean的指定属性
     *
     * @param cls
     * @param fieldName
     * @return
     */
    public static Field getBeanField(Class<?> cls, String fieldName) {
        if (cls == null) {
            return null;
        }
        Field field = null;
        try {
            field = cls.getDeclaredField(fieldName);
        } catch (Exception e) {

        }
        return field;
    }

    /**
     * 设置对应值
     *
     * @param fieldName
     */
    public static void setBeanField(Class<?> cls, Object obj, String fieldName, Object value) throws Exception {

        // 判断字段是否存在
        Field field = getBeanField(cls, fieldName);
        if (field == null) {
            return;
        }
        // 判断字段的set方法是否存在
        String setMethodName = StringUtils.pareSetName(fieldName);
        Method method = getBeanMethod(cls, setMethodName, field.getType());
        if (method == null) {
            return;
        }
        //为空不设置
        if (value == null) {
            return;
        }
        String fieldType = field.getType().getSimpleName();
        if ("String".equals(fieldType)) {
            method.invoke(obj, value.toString());
        } else if ("long".equals(fieldType) || "Long".equals(fieldType)) {
            method.invoke(obj, Long.valueOf(value.toString()));
        } else if ("int".equals(fieldType) || "Integer".equals(fieldType)) {
            method.invoke(obj, value.toString());
        } else if ("double".equals(fieldType) || "Double".equals(fieldType)) {
            method.invoke(obj, Double.valueOf(value.toString()));
        } else if ("float".equals(fieldType) || "Float".equals(fieldType)) {
            method.invoke(obj, Float.valueOf(value.toString()));
        } else if ("boolean".equals(fieldType) || "Boolean".equals(fieldType)) {
            if (value.getClass().equals(Boolean.class)) {
                method.invoke(obj, (Boolean) value);
            } else {
                method.invoke(obj, Boolean.valueOf(value.toString()));
            }
        } else if ("Date".equals(fieldType)) {
            if (value.getClass().equals(Date.class)) {
                method.invoke(obj, (Date) value);
            } else {
                method.invoke(obj, DateUtils.strToDate(value.toString()));
            }
        }
    }

    /**
     * 设置对应值
     *
     * @param fieldName
     */
    public static Object getBeanFieldValue(Class<?> cls, Object obj, String fieldName) throws Exception {

        // 判断字段是否存在
        Field field = getBeanField(cls, fieldName);
        // 判断字段的set方法是否存在
        String getMethodName = StringUtils.pareGetName(fieldName, false);
        // 判断字段的无参get方法是否存在
        Method method = getBeanMethod(cls, getMethodName, new Class[]{});
        Object fieldValue = method.invoke(obj, new Object[]{});
        return fieldValue;
    }
}

StringUtils

/**
 *
 */
package com.zddts.common.utils;

import java.net.URLEncoder;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Luojie
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils {

    /**
     * 合并字符串数组为一个串
     *
     * @param src       String[] 字符串数组
     * @param delimiter 隔开字符
     * @return String
     */
    public static String merge(String[] src, String delimiter) {
        StringBuffer newSrc = new StringBuffer();
        for (int i = 0; i < src.length; i++) {
            if (i < src.length - 1) {
                newSrc.append(src[i]).append(delimiter);
            } else {
                newSrc.append(src[i]);
            }
        }
        return newSrc.toString();
    }

    /**
     * 分解字符串
     *
     * @param str  String
     * @param sect int 分解的段数
     * @param len  int 每段的字符长度
     * @return String[]
     * @throws Exception
     */
    static public String[] split(String str, int sect, int len)
            throws Exception {
        String[] result = new String[sect];
        int j = 0;
        for (j = 0; j < sect; j++) {
            result[j] = "";
        }
        for (j = 0; j < sect; j++) {
            if (str.length() < len * j) {
                break;
            } else if (str.length() < len * (j + 1)) {
                result[j] = str.substring(len * j, str.length());
            } else {
                result[j] = str.substring(len * j, len * (j + 1));
            }
        }
        return result;
    }

    /**
     * 对整个url进行编码转换
     *
     * @param srcStr   url串
     * @param encoding 编码
     * @return String
     */
    public static String URLEncode(String srcStr, String encoding) {
        String[] arrayUrl = srcStr.split("?");
        if (arrayUrl.length <= 1) {
            return srcStr;
        }
        String qryStr = arrayUrl[1];
        String[] arrayQryStr = qryStr.split("&");
        StringBuffer newQryStr = new StringBuffer(120);
        StringBuffer tmp = new StringBuffer(20);
        String param;
        for (int i = 0; i < arrayQryStr.length; i++) {
            param = arrayQryStr[i];
            String[] arrayParam = param.split("=");
            if (arrayParam.length > 1) {
                try {
                    arrayParam[1] = URLEncoder.encode(arrayParam[1], encoding);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                tmp.append(arrayParam[0]).append("=").append(arrayParam[1]);
                arrayQryStr[i] = tmp.toString();
            } else {
                tmp.append(arrayParam[0]).append("=");
                arrayQryStr[i] = tmp.toString();
            }
            newQryStr.append(arrayQryStr[i]).append("&");
        }
        tmp = new StringBuffer(150);
        tmp.append(arrayUrl[0]).append("?").append(newQryStr.toString());
        return tmp.toString();
    }

    /**
     * 用 newString 替换 line 中的所有的 OldString。 不支持正则表达式
     *
     * @param line      原字符串
     * @param oldString 被替换的字符串
     * @param newString 新的要替换oldString的字符串
     * @return 返回所有oldString都被newString替换的字符串
     */
    public static final String replace(String line, String oldString,
                                       String newString) {
        // 如果line是null,直接返回
        if (line == null) {
            return null;
        }
        int i = 0;
        // 如果在line中确实存在oldString那么将进行以下的替换
        if ((i = line.indexOf(oldString, i)) >= 0) {
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = line.indexOf(oldString, i)) > 0) {
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            return buf.toString();
        }
        // 如果在line中没有oldString 返回line
        return line;
    }

    /**
     * 用 newString 替换 line 中的所有的 OldString count返回被替换的数目
     *
     * @param line      原字符串
     * @param oldString 被替换的字符串
     * @param newString 新的要替换oldString的字符串
     * @return 返回所有oldString都被newString替换的字符串
     */
    public static final String replace(String line, String oldString,
                                       String newString, int[] count) {
        if (line == null) {
            return null;
        }
        int i = 0;
        if ((i = line.indexOf(oldString, i)) >= 0) {
            int counter = 0;
            counter++;
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = line.indexOf(oldString, i)) > 0) {
                counter++;
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            count[0] = counter;
            return buf.toString();
        }
        return line;
    }

    /**
     * 做不区分大小写的模式匹配,并用newString 来替换 oldString
     *
     * @param line      原字符串
     * @param oldString 被替换的字符串
     * @param newString 新的要替换oldString的字符串
     * @return 返回所有oldString都被newString替换的字符串
     */
    public static final String replaceIgnoreCase(String line, String oldString,
                                                 String newString) {
        // 如果line是null,直接返回
        if (line == null) {
            return null;
        }
        String lcLine = line.toLowerCase();
        String lcOldString = oldString.toLowerCase();
        int i = 0;
        if ((i = lcLine.indexOf(lcOldString, i)) >= 0) {
            char[] line2 = line.toCharArray();
            char[] newString2 = newString.toCharArray();
            int oLength = oldString.length();
            StringBuffer buf = new StringBuffer(line2.length);
            buf.append(line2, 0, i).append(newString2);
            i += oLength;
            int j = i;
            while ((i = lcLine.indexOf(lcOldString, i)) > 0) {
                buf.append(line2, j, i - j).append(newString2);
                i += oLength;
                j = i;
            }
            buf.append(line2, j, line2.length - j);
            return buf.toString();
        }
        return line;
    }

    /**
     * 从数组中得到字符串的位置
     *
     * @param s    要查询的字符串
     * @param args 待查的数组
     * @return s的位置,没有找到就是-1
     */
    public static int getStrIndex(String s, String args[]) {
        int length = args.length;
        for (int i = 0; i < length; i++) {
            if (args[i].equals(s)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 判断 如果输入的字符为null或者'null',输出空字符串""
     *
     * @param src
     * @return
     */
    public static String nullToEmpty(String src) {
        if (src == null || src.equalsIgnoreCase("NULL")) {

            return "";
        }
        return src;
    }

    /**
     * 将下划线连接的String替换为驼峰风格
     *
     * @param s
     * @return
     */
    public static String toCamelCasing(String s) {
        if (s == null) {
            return s;
        }

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < s.length() - 1; i++) {
            char ch = s.charAt(i);
            if (ch != '_') {
                buffer.append(ch);
            } else {
                char nextChar = s.charAt(i + 1);
                if (nextChar != '_') {
//             if (buffer.toString().length() < 2) {
//                buffer.append(Character.toLowerCase(nextChar));
//             } else {
                    buffer.append(Character.toUpperCase(nextChar));
//             }
                    i++;
                }
            }
        }
        char lastChar = s.charAt(s.length() - 1);
        if (lastChar != '_') {
            buffer.append(lastChar);
        }

        return buffer.toString();
    }

    /**
     * 将驼峰结构的字符串转换为下划线连接的形式
     *
     * @param s
     * @return
     */
    public static String toUnderLine(String s) {
        if (s == null) {
            return s;
        }

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < s.length() - 1; i++) {
            char ch = Character.toLowerCase(s.charAt(i));
            char nextChar = s.charAt(i + 1);
            if (Character.isUpperCase(nextChar)) {
                buffer.append(ch).append('_');
            } else {
                buffer.append(ch);
            }
        }
        char lastChar = s.charAt(s.length() - 1);
        buffer.append(Character.toLowerCase(lastChar));

        return buffer.toString();
    }

    /**
     * 将首字母小写
     *
     * @param s
     * @return
     */
    public static String lowerFirstChar(String s) {
        if (s == null || s.trim().equals("")) {
            return null;
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(Character.toLowerCase(s.charAt(0)))
                .append(s.substring(1));
        return buffer.toString();
    }

    /**
     * 将首字母大写
     *
     * @param s
     * @return
     */
    public static String upperFirstChar(String s) {
        if (s == null || s.trim().equals("")) {
            return null;
        }
        StringBuffer buffer = new StringBuffer();
        buffer.append(Character.toUpperCase(s.charAt(0)))
                .append(s.substring(1));
        return buffer.toString();
    }

    /**
     * 拼接某属性get 方法
     *
     * @param isBooleanType 属性是否为boolean型
     * @return
     */
    public static String pareGetName(String fieldName, Boolean isBooleanType) {
        String str = StringUtils.upperFirstChar(fieldName);
        if (str == null) {
            return null;
        }
        if (isBooleanType) {
            return "is" + str;
        } else {
            return "get" + str;
        }
    }

    /**
     * 拼接某属性set 方法
     *
     * @return
     */
    public static String pareSetName(String fieldName) {
        String str = StringUtils.upperFirstChar(fieldName);
        if (str == null) {
            return null;
        }
        String pro = "set" + str;
        return pro;
    }

    /**
     * 方法说明:判断字符串是否为空
     *
     * @param paramString
     * @return
     */
    public static boolean nullOrBlank(String paramString) {
        return (paramString == null) || (paramString.trim().equals(""));
    }

    /**
     * 方法说明:判断字符串是否为空
     * List
     *
     * @return
     */
    public static boolean notNullOrBlankList(List list) {

        if (list == null || list.size() == 0) {
            return false;
        }
        return true;
    }

    /**
     * 方法说明:字符串为空时给默认值
     *
     * @param str
     * @param defaultValue
     * @return
     */
    public static String strNvl(String str, String defaultValue) {
        if (nullOrBlank(str)) {
            return defaultValue;
        }
        return str;
    }

    /**
     * 方法说明:字符串为空时给默认值
     *
     * @param strObj
     * @param defaultValue
     * @return
     */
    public static String strObjNvl(Object strObj, String defaultValue) {
        String str = null;
        if (strObj != null) {
            str = strObj.toString();
        }
        return strNvl(str, defaultValue);
    }

    /**
     * 方法说明:获取第N个a字符后面的所有字符
     * <p>
     * <p>
     * Author: 高宝阳 Create Date: May 5, 2016 6:04:10 PM History: May 5, 2016
     * 6:04:10 PM Administrator Created.
     *
     * @param sChar
     * @param n
     * @return
     */
    public static String getNCharAfter(String sInput, String sChar, int n) {
        // 这里是获取sChar符号的位置
        String str = null;
        int m = 1;
        int i = 0;
        while (sInput.indexOf(sChar, i) >= 0) {
            i = sInput.indexOf(sChar, i) + 1;
            if (n == m) {
                str = sInput.substring(i, sInput.length());
                break;
            }
            m = m + 1;
        }
        return str;
    }

    /**
     * 根据传入的字符串判断将来的数组长度,用于系统参数的解析
     *
     * @param sInput 字符串
     * @return
     * @throws Exception
     */
    public static int getArrLen(String sInput) throws Exception {
        int len = 0;
        int i = 0;
        while (sInput.indexOf("$", i) > 0) {
            i = sInput.indexOf("$", i) + 1;
            len = len + 1;
        }
        return len;
    }

    /**
     * 字符串解释成数组
     *
     * @param sInput 字符串格式:例如:w$m$n$o$p$ w: 位数;m、n、o、p分别为字符串;如实际的例子:4$122$+$01$1$
     * @return
     * @throws Exception
     */
    public static String[] stringParse(String sInput) throws Exception {
        String[] sRet = null;
        try {
            int len = getArrLen(sInput);
            int m = -1;
            sRet = new String[len];
            for (int j = 0; j < len; j++) { // 数组
                sRet[j] = sInput.substring(m + 1, sInput.indexOf("$", m + 1));
                m = sInput.indexOf("$", m + 1);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new Exception(e.getMessage());
        }
        return sRet;
    }

    /**
     * replaceBlank
     *
     * @param in
     * @return
     * @description replaceBlank
     */
    public static String replaceBlank(String in) {
        Pattern p = Pattern.compile("\\s*|\t|\r|\n");
        Matcher m = p.matcher(in);
        String after = m.replaceAll("");
        return after;
    }

    /**
     * 删除起始字符
     *
     * @param str
     * @return
     * @author xxj 2017年4月27日
     */
    public static String trimStart(String str, String trim) {
        if (str == null) {

            return null;
        }
        return str.replaceAll("^(" + trim + ")+", "");
    }

    /**
     * 删除末尾字符
     *
     * @param str
     * @return
     * @author xxj 2017年4月27日
     */
    public static String trimEnd(String str, String trim) {
        if (str == null)
            return null;
        return str.replaceAll("(" + trim + ")+$", "");


    }

    public static Object nullToDefault(Object obj, Object def) {
        if (obj == null) {
            return def;
        }
        return obj;
    }

    private static final String UNIT = "万千佰拾亿千佰拾万千佰拾元角分";
    private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";
    private static final double MAX_VALUE = 9999999999999.99D;

    public static String changeMoney(double v) {
        if (v < 0 || v > MAX_VALUE) {
            return "参数非法!";
        }
        long l = Math.round(v * 100);
        if (l == 0) {
            return "零元整";
        }
        String strValue = l + "";
        // i用来控制数
        int i = 0;
        // j用来控制单位
        int j = UNIT.length() - strValue.length();
        String rs = "";
        boolean isZero = false;
        for (; i < strValue.length(); i++, j++) {
            char ch = strValue.charAt(i);
            if (ch == '0') {
                isZero = true;
                if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') {
                    rs = rs + UNIT.charAt(j);
                    isZero = false;
                }
            } else {
                if (isZero) {
                    rs = rs + "零";
                    isZero = false;
                }
                rs = rs + DIGIT.charAt(ch - '0') + UNIT.charAt(j);
            }
        }
        if (!rs.endsWith("分")) {
            rs = rs + "整";
        }
        rs = rs.replaceAll("亿万", "亿");
        return rs;
    }

    public static boolean isBlank(String str) {
        if (str == null || "".equals(str.trim())) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean isNotBlank(String str) {
        if (str != null && !"".equals(str.trim())) {
            return true;
        } else {
            return false;
        }
    }

    public static String isGoodPat(String patNo) {
        patNo = patNo.replaceFirst("[a-zA-Z]*", "").replace(".", "").replace(" ", "");
        if (!patNo.substring(0, patNo.length() - 1).matches("[0-9]*$") || (patNo.length() != 13 && patNo.length() != 7)) {
            return null;
        }
        return patNo;
    }

    /**
     * 更具专利号判断专利类型
     *  一定要是中国13位专利
     * @param patNo
     * @return
     */
    public static String getPatType(String patNo) {

        if (StringUtils.isEmpty(patNo) || patNo.length() <= 5)
            return null;

        String patType = patNo.substring(4, 5);

        if ("8".equals(patType))
            patType = "1";

        if ("9".equals(patType))
            patType = "2";


        return patType;

    }

    public static void main(String args[]) {
        System.out.print(isGoodPat("20171141704x"));
    }

}

使用:

需要注解翻译的BO对象属性上加上注解DataDict ,dict是指标准码的编码或者用户UserBo的属性 (字典名称),

source 值字段翻译值的来源

//汇聚类的字典解析相应配置上 transFerLineColumn 如逗号拆分的配置“,”

字典配置:1 = 出售  2 =结算

数据库聚合存储的为1,2 需要翻译的

效果如图:

//用户字段使用方法

dao层 使用:

或者service 层  使用:

对要数据字典转换的方法加上DataDictClass注解

执行效果

                                     码累了就关注下面公众号领红包下个单点个外卖或者下午茶什么的吧,是的鄙人向生活低下了头~~~~

                                                                  

 

  • 13
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 23
    评论
你好!实现点赞和评论功能可以使用Spring Boot作为后端框架,Redis作为缓存数据库,MySQL作为持久化数据库,UniApp作为前端框架。以下是一个简单的实现步骤: 1. 创建Spring Boot项目并配置MySQLRedis的连接。 2. 创建实体类,如User、Post等,用于表示用户和帖子。 3. 创建MySQL数据库表,包括用户表和帖子表。 4. 使用Spring Data JPA或MyBatis等框架进行数据库操作,实现用户和帖子的增删改查功能。 5. 在帖子表中添加字段用于存储点赞数和评论数。 6. 在后端编写点赞和评论的接口,分别处理点赞和评论的业务逻辑。 - 点赞接口可以接收用户ID和帖子ID,将点赞数加一,并更新数据库。 - 评论接口可以接收用户ID、帖子ID和评论内容,将评论数加一,并将评论保存到数据库。 7. 使用Redis进行缓存,可以将点赞数和评论数存储在Redis中,以提高访问速度。 - 在点赞接口中,先查询Redis中是否存在点赞数,如果存在则直接返回;否则从数据库中查询并存储到Redis中。 - 在评论接口中,同样先查询Redis中是否存在评论数,如果存在则直接返回;否则从数据库中查询并存储到Redis中。 8. 在UniApp中使用Vue.js等技术进行前端开发,调用后端提供的接口实现点赞和评论的功能。 - 在页面中展示帖子列表,并显示点赞数和评论数。 - 点击点赞按钮时,调用后端的点赞接口,并更新页面上的点赞数。 - 点击评论按钮时,调用后端的评论接口,并更新页面上的评论数。 以上是一个简单的实现方案,具体的细节还需要根据你的实际需求进行调整和完善。希望对你有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boomLJIE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值