• hibernate原生SQL查询结果直接转换为实体类对象


    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));
        }
    
    }
  • 相关阅读:
    比较全局变量、全局静态变量、局部变量、局部静态变量的区别
    《Effective C++》——条款20:宁以pass-by-reference-to-const替换pass-by-value
    《Effective C++》——条款17:以独立语句将newed对象置入智能指针
    auto_ptr类
    选择排序
    归并排序
    《Effective C++》——条款08:别让异常逃离析构函数
    使用ResourceBundle读取配置文件
    CSS cursor 属性改变鼠标的样式
    JDBC preparedStatement分页和统计,批处理和事务
  • 原文地址:https://www.cnblogs.com/Ebird/p/14218156.html
Copyright © 2020-2023  润新知