实体与数据库字段转换

想将实体类字段转为数据库字段,找了半天只找到一个这样的例子:

  /**
     * 对象属性转换为数据库字段。例如:userName => user_name
     * 
     * @param property
     *            对象属性
     */
    public static String propertyToField(String property) {
        if (StringUtils.isEmpty(property)) {
            return "";
        }
        if (property.length() == 1) {
            return property.toLowerCase();
        }

        char[] chars = property.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (i == 0) {
                sb.append(StringUtils.lowerCase(CharUtils.toString(c)));
            } else {
                if (CharUtils.isAsciiAlphaUpper(c)) {
                    sb.append("_" + StringUtils.lowerCase(CharUtils.toString(c)));
                } else {
                    sb.append(c);
                }
            }
        }
        return sb.toString();
    }

一般情况下,这个方法都是满足需求的,可以测试一下:

System.out.println(propertyToField("UserName")); // user_name
System.out.println(propertyToField("sUserName")); // s_user_name
System.out.println(propertyToField("isUserName")); // is_user_name
System.out.println(propertyToField("age")); // age

但是如果实体类中,出现连续的大写字母(这种情况不符合java规范),就会很怪异:

System.out.println(propertyToField("settID")); // sett_i_d
System.out.println(propertyToField("APartyName")); // a_party_name

看了下JPA自动把实体类字段转为数据库字段的效果,发现它直接跳过了连续大写字母,只在形如"..aAa..."这样的情况中做转换

于是写了一个将字符串中,连续两个及两个以上的字符替换成小写的方法。代码如下:

  /**
     * 将property字符串中,连续两个及两个以上的字符替换成小写
     */
    private static String lowerConStr(String property) {
        // 记录连续大写字母。元素组成:连续大写字母首个字母下标 + "_" + 连续大写字母个数
        List<String> uppList = new ArrayList<>();

        String info = "";
        char[] chars = property.toCharArray();
        char c = chars[0];
        int count = 1; // 记录连续大写字母个数
        for (int i = 1; i < chars.length; i++) {
            // 上个字符是否大写
            boolean isSep = CharUtils.isAsciiAlphaUpper(c);

            char s = chars[i];
            // 当前字符是否大写
            boolean isCurrUp = CharUtils.isAsciiAlphaUpper(s);

            // 连续大写,记录下来
            if (isSep && isCurrUp) {
                if (StringUtils.isEmpty(info)) {
                    info = (i - 1) + "_";
                }
                count++;
                if (i == chars.length - 1) {
                    String wordInfo = info + count;
                    uppList.add(wordInfo);
                }
            } else {
                if (count > 1) {
                    String wordInfo = info + count;
                    uppList.add(wordInfo);
                    count = 1;
                    info = "";
                }
            }
            c = s;
        }
        String lower = lower(property, uppList);
        // System.out.println(property + " => " + lower);
        return lower;
    }

    /**
     * 将property中连续大写字母,根据uppList记录,转为小写
     */
    private static String lower(String property, List<String> uppList) {
        StringBuilder sb = new StringBuilder(property);
        for (String str : uppList) {
            String[] arr = str.split("_");
            int index = Integer.valueOf(arr[0]);
            int count = Integer.valueOf(arr[1]);

            String r = property.substring(index, index + count);
            sb.replace(index, index + count, r.toLowerCase());
        }
        return sb.toString();
    }

然后在最上面的propertyToField方法中增加一行:

if (property.length() == 1) {
    return property.toLowerCase();
}

// 将property字符串中,连续两个及两个以上的字符替换成小写
property = lowerConStr(property);

char[] chars = property.toCharArray();
StringBuffer sb = new StringBuffer();
 ...

再来看测试结果,都是正确的:

System.out.println(propertyToField("UserName")); // user_name
System.out.println(propertyToField("sUserName")); // s_user_name
System.out.println(propertyToField("isUserName")); // is_user_name
System.out.println(propertyToField("age")); // age
System.out.println(propertyToField("settID")); // settid
System.out.println(propertyToField("APartyName")); // aparty_name

 

最后再送一个在网上找到的,数据库字段转换为实体类字段的方法:

  /**
     * 字段转换成对象属性 例如:user_name to userName
     * 
     * @param field
     * @return
     */
    public static String fieldToProperty(String field) {
        if (null == field) {
            return "";
        }
        char[] chars = field.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (c == '_') {
                int j = i + 1;
                if (j < chars.length) {
                    sb.append(StringUtils.upperCase(CharUtils.toString(chars[j])));
                    i++;
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

 

posted @ 2018-10-26 16:20  仅此而已-远方  阅读(2612)  评论(1编辑  收藏  举报