zoukankan      html  css  js  c++  java
  • 实体与数据库字段转换

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

      /**
         * 对象属性转换为数据库字段。例如: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();
        }
  • 相关阅读:
    什么时候应该使用C#的属性
    Unicode和字符集小结
    C#编译器怎么检查代码是否会执行
    C#中如何操作2个list
    用Windbg来看看CLR的JIT是什么时候发生的
    bzoj-1579: [Usaco2009 Feb]Revamping Trails 道路升级
    次小生成树
    bzoj-3687: 简单题
    bzoj-3669: [Noi2014]魔法森林
    uva 11732 (trie树)
  • 原文地址:https://www.cnblogs.com/xuwenjin/p/9857071.html
Copyright © 2011-2022 走看看