当前位置: 代码迷 >> SQL >> 在Hibernate中施行传统的sql语句,并将结果Set到VO中
  详细解决方案

在Hibernate中施行传统的sql语句,并将结果Set到VO中

热度:62   发布时间:2016-05-05 13:19:51.0
在Hibernate中执行传统的sql语句,并将结果Set到VO中
最近在整合springsecurity,由于表间都是用的多对多,所以当要join取数据时,传统的ORM思想带来性能问题,HQL语句写的太大,所以就想采用传统的SQL.现记录如下,留做后用.
这里只留关键程序.其它的忽略.
/**根据手工创建的sql语句来查询,返回指定的class对象	 * @param sqlQuery	 * @param clazz	 * @return	 */	public List<? extends BaseModel>  findListBySQLQuery(String sqlQuery, Class<? extends BaseModel> clazz)	{		Query q= getSession().createSQLQuery(sqlQuery);		q.setResultTransformer(new CustomResultTransformer(clazz));		return q.list();	}

如果你的系统里没有BaseModel,将上面的去掉就是了.
CustomResultTransformer 是从一个同学的博客里抄来的.这里就不写出来了,大家可以在javaeye上搜索一下.

最后的效果就是,比如执行SELECT a.id, a.roleName FROM dbo.role a INNER JOIN groupRole c ON a.roleId = c.roleId INNER JOIN dbo.groups b ON c.groupID = b.groupID inner join dbo.groupUser d on b.groupId=d.groupID inner join dbo.users e on d.userid=e.userid WHERE (e.userName =?).然后我们有一个VO类userinfo,那么这个VO类里的id,roleName都会被set上值,其它的属性忽略.并且不报错.
人生从此就舒坦了.
当然,学好HQL才是我们的正途,这些歪门邪道的还是少用的好.

下面是最新的代码,解决了3个问题,
1.如果没有对应的set则不注入。以前是报错。
2.如果从数据库中取出的是空,也不注入。以前是报错。
3.如果从数据库中取出的值 类型不对,刚强制转换为setter需要的值。
/* * (#)CustomResultTransformer.java 1.0 2010-6-21   */package com.framework.hibernate.util;import java.lang.reflect.Field;import java.util.List;import org.apache.commons.beanutils.ConvertUtils;import org.apache.commons.lang.ArrayUtils;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.ResultTransformer; /** * 本类的使用意义 2.public List<?> findObjectBySql(String queryString,Class<?> pojoClass){ 3. //使用SQL构造查询对象,此SQL是可以被JDBC接受的SQL,如SELECT * FROM XXX_TABLE 4. Query query = * this.getSession().createSQLQuery(queryString); 5. //设置结果集转换器,这是本文重点所在 6. query.setResultTransformer(new CustomResultTransformer(pojoClass)); 7. //返回查询结果 8. return query.list(); * 自定义的数据库字库转换成POJO */public class CustomResultTransformer implements ResultTransformer{		private static final long		serialVersionUID	= 1L;		private final Class				resultClass;		private Class[]					clazz;		private Setter[]				setters;		private final PropertyAccessor	propertyAccessor;		public CustomResultTransformer ( Class resultClass )	{		if ( resultClass == null )			throw new IllegalArgumentException ( "resultClass cannot be null" );		this.resultClass = resultClass;		propertyAccessor = new ChainedPropertyAccessor ( new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor ( resultClass , null ),				PropertyAccessorFactory.getPropertyAccessor ( "field" ) } );	}		// 结果转换时,HIBERNATE调用此方法	public Object transformTuple ( Object[] tuple , String[] aliases )	{		Object result;				try		{			if ( setters == null )			{// 首先初始化,取得目标POJO类的所有SETTER方法				setters = new Setter[aliases.length];				clazz = new Class[aliases.length];				for ( int i = 0 ; i < aliases.length ; i++ )				{					String alias = aliases[i];					if ( alias != null )					{						// 我的逻辑主要是在getSetterByColumnName方法里面,其它都是HIBERNATE的另一个类中COPY的						// 这里填充所需要的SETTER方法						setters[i] = getSetterByColumnName ( alias , i );					}				}			}			result = resultClass.newInstance ( );						// 这里使用SETTER方法填充POJO对象			for ( int i = 0 ; i < aliases.length ; i++ )			{				if ( setters[i] != null && tuple[i] != null )				{					try					{						setters[i].set ( result , ConvertUtils.convert ( tuple[i] , clazz[i] ) , null );					} catch ( SecurityException e )					{						e.printStackTrace ( );					}				}			}		} 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;	}		// 根据数据库字段名在POJO查找JAVA属性名,参数就是数据库字段名,如:USER_ID	private Setter getSetterByColumnName ( String alias , int index )	{		// 取得POJO所有属性名		Field[] fieldsSuperClass = resultClass.getSuperclass ( ).getDeclaredFields ( );		Field[] fieldsMine = resultClass.getDeclaredFields ( );		Field[] fields = (Field[]) ArrayUtils.addAll ( fieldsSuperClass , fieldsMine );		if ( fields == null || fields.length == 0 )		{			throw new RuntimeException ( "实体" + resultClass.getName ( ) + "不含任何属性" );		}		// 把字段名中所有的下杠去除		String proName = alias.replaceAll ( "_" , "" ).toLowerCase ( );		for ( Field field : fields )		{			if ( field.getName ( ).toLowerCase ( ).equals ( proName ) )			{				// 去除下杠的字段名如果和属性名对得上,就取这个SETTER方法				clazz[index] = field.getType ( );				return propertyAccessor.getSetter ( resultClass , field.getName ( ) );			}		}		//throw new RuntimeException("找不到数据库字段 :" + alias + " 对应的POJO属性或其getter方法,比如数据库字段为USER_ID或USERID,那么JAVA属性应为userId");		return null;	}		public List transformList ( List collection )	{		return collection;	}	}
  相关解决方案