hibernate结果集转换器ResultTransformer。基于别名实现(一)

2014-11-24 08:39:19 · 作者: · 浏览: 0
public class AliasedResultTransformer extends AliasedTupleSubsetResultTransformer {
	private static final Logger logger = LoggerFactory.getLogger(AliasedResultTransformer.class);

	private static final long serialVersionUID = 1L;
	private final Class< > resultClass;// 结果集类型
	private String[] columnAlias = {};// 查询语句栏位别名
	private ConstructorAccess< > constructorAccess;// 构造函数访问器
	private MethodAccess methodAccess;// 方法访问器
	private String[] methodNames;// 方法名
	private int[] methodIndexs;// 方法索引
	private Class< >[][] argsTypes;// 栏位别名参数类型/方法参数类型
	private String sql;// 查询语句
	private boolean sqlQueryAll = false;// sql查询所有栏位,默认false
	private boolean hqlQueryAll = false;// hql查询所有栏位,默认false

	/**
	 * 构造基于sql/hql别名的结果集转换器
	 * 
	 * @param resultClass
	 *            结果集类型
	 * @param sql
	 *            sql/hql语句
	 */
	public  AliasedResultTransformer(Class resultClass, String sql) {
//		if (sql.indexOf("select new") > -1) {
//			throw new IllegalStateException("hql使用了select new JavaBean() from...方式,就不需要设置query.setResultTransformer()了。");
//		}
//		if (resultClass == null) {
//			throw new IllegalArgumentException("resultClass cannot be null");
//		}
		this.resultClass = resultClass;
		this.sql = sql;
		this.constructorAccess = AsmUtils.get().createConstructorAccess(resultClass);
		this.methodAccess = AsmUtils.get().createMethodAccess(resultClass);

		QueryStatement statement = QueryStatementCache.getInstance().get(sql);
		if (statement != null) {
			this.methodIndexs = statement.getMethodIndexs();
			this.columnAlias = statement.getColumnAlias();
			this.argsTypes = statement.getArgsTypes();
			this.hqlQueryAll = statement.isHqlQueryAll();
			this.sqlQueryAll = statement.isSqlQueryAll();
		} else {
			if (sql.indexOf("*") > 0 && sql.indexOf("count(*)") < 0) {
				this.sqlQueryAll = true;
			} else {
				this.hqlQueryAll = ColumnAliasParser.getInstance().isQueryAll(sql);
				if (hqlQueryAll) {
					QueryStatement stmt = new QueryStatement();
					stmt.setHqlQueryAll(hqlQueryAll);
					QueryStatementCache.getInstance().put(sql, stmt);
				}
			}

			if (!hqlQueryAll && !sqlQueryAll) {// 不是查询所有栏位,需要重新解析sql/hql
				this.columnAlias = ColumnAliasParser.getInstance().parseColumnAlias(sql, true);
				String[] tempMethodNames = this.methodAccess.getMethodNames();
				this.methodNames = new String[columnAlias.length];
				this.methodIndexs = new int[columnAlias.length];
				this.argsTypes = new Class< >[columnAlias.length][];
				Class< >[][] tempArgsTypes = this.methodAccess.getParameterTypes();
				for (int i = 0; i < columnAlias.length; i++) {
					for (int j = 0; j < tempMethodNames.length; j++) {
						String methodName = tempMethodNames[j];
						if (methodName.startsWith("set")
								&& columnAlias[i].equals(StringUtils.uncapitalize(methodName.substring(3)))) {
							methodNames[i] = methodName;
							methodIndexs[i] = this.methodAccess.getIndex(methodName);
							argsTypes[i] = tempArgsTypes[j];
						}
					}
				}

				QueryStatement stmt = new QueryStatement();
				stmt.setArgsTypes(argsTypes);
				stmt.setColumnAlias(columnAlias);
				stmt.setMethodIndexs(methodIndexs);
				stmt.setHqlQueryAll(hqlQueryAll);
				stmt.setSqlQueryAll(sqlQueryAll);
				QueryStatementCache.getInstance().put(sql, stmt);
			}

		}

	}

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

	public Object transformTuple(Object[] tuple, String[] aliases) {
		if (hqlQueryAll) {
			return (tuple.length == 1   tuple[0] : tuple);
		} else if (sqlQueryAll) {
			this.columnAlias = aliases;

			// 没有解析过,将解析
			if (methodIndexs == null || methodIndexs.length <= 0
					|| argsTypes == null || argsTypes.length <= 0) {
				this.methodIndexs = new int[columnAlias.length];
				this.argsTypes = new Class< >
[columnAlias.length][]; Class< >[][] tempArgsTypes = this.methodAccess.getParameterTypes(); for (int i = 0; i < aliases.length; i++) { String methodName = "set" + CamelCaseUtils.toCapitalizeCamelCase(aliases[i]); try { methodIndexs[i] = methodAccess.getIndex(methodName); argsTypes[i] = tempArgsTypes[methodIndexs[i]]; } catch (IllegalArgumentException e) { logger.info("方法[" + methodName + "]不存在,可能是Entity关联栏位。" + e.getMessage()); } } QueryStatement stmt = new QueryStatement(); stmt.setArgsTypes(argsTypes); stmt.setColumnAlias(columnAlias); stmt.setMethodIndexs(methodIndexs); stmt.setHqlQueryAll(hqlQueryAll); stmt.setSqlQueryAll(sqlQueryAll); QueryStatementCache.getInstance().put(sql, stmt); } } Object entity = constructorAccess.newInstance(); for (int i = 0; i < aliases.length; i++) { methodAccess.invoke(entity, methodIndexs[i], tuple[i]); } return entity; } /** * sql栏位别名对应的类型 * * @return 别名类型 * @author yinlei date 2013-6-9 下午7:50:50 */ public Class< >[][] getArgsTypes() { return argsTypes; } /** * 获取sql中栏位别名数组 * * @return 栏位别名 * @author yinlei date 2013-6-9 下午7:50:04 */ public String[] getColumnAlias() { return columnAlias; } public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } AliasedResultTransformer that = (AliasedResultTransformer) o; if (!resultClass.equals(that.resultClass)) { return false; } if (!Arrays.equals(columnAlias, that.columnAlias)) { return false; } return true; } public int hashCode() { int result = resultClass.hashCode(); result = 31 * result + (columnAlias != null Arrays.hashCode(columnAlias) : 0); return result; } }


public class AliasedResultTransformer extends AliasedTupleSubsetResultTransformer {
	private static final Logger logger = LoggerFactory.getLogger(AliasedResultTransformer.class);

	private static final long serialVersionUID = 1L;
	private final Class< > resultClass;// 结果集类型
	private String[] columnAlias = {};// 查询语句栏位别名
	private ConstructorAccess< > constructorAccess;// 构造函数访问器
	private MethodAccess methodAccess;// 方法访问器
	private Strin