hibernate 或jpa 中使用 AliasToBeanResultTransformer 自定义类型转换ResultTransformer 下划线转驼峰

jpa中使用 sql查询时,返回结果直接转为实体bean的实现,

需要自定义一个ResultTransformer,如下,

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.property.ChainedPropertyAccessor;
import org.hibernate.property.PropertyAccessor;
import org.hibernate.property.PropertyAccessorFactory;
import org.hibernate.property.Setter;
import org.hibernate.transform.AliasToBeanResultTransformer;

/**
 * @Description : 
 * @Autor : xiongjinpeng  jpx_011@163.com
 * @Date  : 2016年3月18日 上午10:05:00 
 * @version : 
 */
public class SelfResultTransformer extends AliasToBeanResultTransformer{
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static Logger logger = Logger.getLogger(SelfResultTransformer.class);

    public <T> SelfResultTransformer(Class<T> resultClass)
    {
        super(resultClass);
        if(resultClass == null)
        {
            throw new IllegalArgumentException("resultClass cannot be null");
        } else
        {
            isInitialized = false;
            this.resultClass = resultClass;
            return;
        }
    }

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

    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((new StringBuilder()).append("Could not instantiate resultclass: ").append(resultClass.getName()).toString());
        }
        catch(IllegalAccessException e)
        {
            throw new HibernateException((new StringBuilder()).append("Could not instantiate resultclass: ").append(resultClass.getName()).toString());
        }
        return result;
    }

    private void initialize(String aliases[])
    {
        PropertyAccessor propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] {
            PropertyAccessorFactory.getPropertyAccessor(resultClass, null), PropertyAccessorFactory.getPropertyAccessor("field")
        });
        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;
                alias = UnderlineToCamelUtil.underlineToCamel(alias);
                try {
                    setters[i] = propertyAccessor.getSetter(resultClass, alias);
                } catch (Exception e) {
                    logger.warn(resultClass+" property "+alias+" not found");
                }
                
            }
        }

        isInitialized = true;
    }

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

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

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

    private final Class resultClass;
    private boolean isInitialized;
    private String aliases[];
    private Setter setters[];

}


下划线转驼峰工具类,

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

/**
 * @Description : 
 * @Autor : xiongjinpeng  jpx_011@163.com
 * @Date  : 2016年3月18日 上午10:20:47 
 * @version : 
 */
public class UnderlineToCamelUtil {

    public static final char UNDERLINE='_';
    public static String camelToUnderline(String param){
        if (param==null||"".equals(param.trim())){
            return "";
        }
        int len=param.length();
        StringBuilder sb=new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c=param.charAt(i);
            if (Character.isUpperCase(c)){
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
    /**
     * 下划线转驼峰
     * @param param
     * @return
     */
    public static String underlineToCamel(String param){
        if (param==null||"".equals(param.trim())){
            return "";
        }
        int len=param.length();
        StringBuilder sb=new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c=param.charAt(i);
            if (c==UNDERLINE){
               if (++i<len){
                   sb.append(Character.toUpperCase(param.charAt(i)));
               }
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
    public static String underlineToCamel2(String param){
        if (param==null||"".equals(param.trim())){
            return "";
        }
        StringBuilder sb=new StringBuilder(param);
        Matcher mc= Pattern.compile("_").matcher(param);
        int i=0;
        while (mc.find()){
            int position=mc.end()-(i++);
            //String.valueOf(Character.toUpperCase(sb.charAt(position)));
            sb.replace(position-1,position+1,sb.substring(position,position+1).toUpperCase());
        }
        return sb.toString();
    }
	public static void main(String[] args) {
		System.out.println(underlineToCamel("a_b_c"));
		System.out.println(underlineToCamel2("a_b_c"));
	}

}

  实际调用如下,

private EntityManager em;
public <K> K getObjectBySql(String sql,Object[] params,Class<K> k){ Query query = em.createNativeQuery(sql); if(params!=null){ for(int i=0,len=params.length;i<len;i++){ Object param=params[i]; query.setParameter(i+1, param); } } query.unwrap(SQLQuery.class).setResultTransformer(new SelfResultTransformer(k)); K object =(K) query.getSingleResult(); return object; }

  

 jpa中调用的是hibernate中的代码,所以hibernate的sql查询类似

 

posted on 2016-03-18 11:21  xiong2012  阅读(7731)  评论(0编辑  收藏  举报