hibernate原生的结果解析器对sql查询字段的命名要求比较严格,必须跟实体属性名称一致,而往往字段都是驼峰命名,所以重写了一个,优先按照驼峰命名映射,然后是直接匹配

使用的时候,直接设置结果解析器,指定接收结果类型就行了

SQLQuery query = ...
query.setResultTransformer( new AliasedToHumpResultTransformer(StudentOrderChange.class));
List<StudentOrderChange> result = query.list();

 

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.hibernate.HibernateException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyChainedImpl;
import org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl;
import org.hibernate.property.access.spi.Setter;
import org.hibernate.transform.AliasedTupleSubsetResultTransformer;


/**
 * 别名转驼峰命名结果解析器
 * @author liu08dzxx
 *
 */
public class AliasedToHumpResultTransformer extends AliasedTupleSubsetResultTransformer {

    private static final long serialVersionUID = 4367861232547899096L;

//    private static Logger LOGGER = LoggerFactory.getLogger(AliasedToHumpResultTransformer.class);
    
    private final Class<?> resultClass;
    private boolean isInitialized;
    private String[] aliases;
    private Setter[] setters;

    public AliasedToHumpResultTransformer(Class<?> resultClass) {
        if (resultClass == null) {
            throw new IllegalArgumentException("resultClass cannot be null");
        }
        isInitialized = false;
        this.resultClass = resultClass;
    }

    @Override
    public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) {
        return false;
    }

    @Override
    public Object transformTuple(Object[] tuple, String[] aliases) {
        Object result;
        try {
            if (!isInitialized) {
                initialize(aliases);
            } 
            else {
                check(aliases);
            }
            result = resultClass.newInstance();
            for (int i = 0; i < aliases.length; i++) {
                if (setters[i] != null) {
                    setters[i].set(result, tuple[i], null);
                }
            }
        } catch (InstantiationException e) {
            throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
        } catch (IllegalAccessException e) {
            throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
        }

        return result;
    }

    private void initialize(String[] aliases) {
        PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl(
                PropertyAccessStrategyBasicImpl.INSTANCE ,PropertyAccessStrategyFieldImpl.INSTANCE);
        this.aliases = new String[aliases.length];
        setters = new Setter[aliases.length];
        for (int i = 0; i < aliases.length; i++) {
            String alias = aliases[i];
            //
            if (alias != null) {
                this.aliases[i] = alias;
                try {
                    //修改为驼峰命名,如果找不到就不赋值
                    setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, lineToHump(alias)).getSetter();
                }catch(PropertyNotFoundException e) {
                    //todo 不知道是否有必要,暂时不做
                    try {
                        //找不到,尝试直接使用字段名作为属性名
                        setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, alias).getSetter();
                    }catch(PropertyNotFoundException e2) {
                        //还找不到,尝试直接使用去掉下划线的方式命名
                        try {
                            setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, alias.replace("_", "")).getSetter();
                        }catch(PropertyNotFoundException e3) {
//                            LOGGER.warn("结果集字段"+alias+",在对象"+resultClass.getName()+"中没有属性对应,不使用的字段建议不要加入结果集");
                            setters[i] = null;
                        }
                    }
                }
            }
        }
        isInitialized = true;
    }

    private void check(String[] aliases) {
        if (!Arrays.equals(aliases, this.aliases)) {
            throw new IllegalStateException("aliases are different from what is cached; aliases="
                    + Arrays.asList(aliases) + " cached=" + Arrays.asList(this.aliases));
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        AliasedToHumpResultTransformer that = (AliasedToHumpResultTransformer) o;
        if (!resultClass.equals(that.resultClass)) {
            return false;
        }
        if (!Arrays.equals(aliases, that.aliases)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = resultClass.hashCode();
        result = 31 * result + (aliases != null ? Arrays.hashCode(aliases) : 0);
        return result;
    }



    private static Pattern linePattern = Pattern.compile("_(\\w)");

    /** 下划线转驼峰 */
    public static String lineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = linePattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    private static Pattern humpPattern = Pattern.compile("[A-Z]");

    /** 驼峰转下划线, */
    public static String humpToLine2(String str) {
        Matcher matcher = humpPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    public static void main(String[] args) {
        String name = "user_type";
        System.out.println(lineToHump(name));
    }

}

 

posted on 2020-12-31 17:45  菜鸟你够了  阅读(707)  评论(0编辑  收藏  举报