All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jquicker.persistent.rdb.dao.DaoHandler Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package com.jquicker.persistent.rdb.dao;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import com.jquicker.args.ArgsNameDiscoverer;
import com.jquicker.args.LocalVariableTableArgsNameDiscoverer;
import com.jquicker.args.MethodInfo;
import com.jquicker.commons.util.ObjectUtils;
import com.jquicker.exception.ResultSetParserException;
import com.jquicker.model.BaseEntity;
import com.jquicker.model.ResultMap;
import com.jquicker.persistent.rdb.executor.SQLExecutor;
import com.jquicker.persistent.rdb.executor.ExecutorFactory;
import com.jquicker.persistent.rdb.model.FinalSQL;
import com.jquicker.persistent.rdb.model.Relation;
import com.jquicker.persistent.rdb.model.Relation.RelationType;
import com.jquicker.persistent.rdb.model.DynamicSQL;
import com.jquicker.persistent.rdb.sqlfile.SQLManager;
import com.jquicker.persistent.rdb.sqlfile.SQLParser;
import com.jquicker.persistent.rdb.util.ResultSetUtils;

/**
 * @author OL
 */
public class DaoHandler implements InvocationHandler {

	private ArgsNameDiscoverer discover = new LocalVariableTableArgsNameDiscoverer();
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		String className = method.getDeclaringClass().getName();
		String methodName = method.getName();
		DynamicSQL sql = SQLManager.getSQL(className, methodName);
		if(sql == null) {
			throw new SQLException("未找到SQL语句[" + className + "." + methodName + "]");
		}
		
		MethodInfo methodInfo = SQLParser.getMethodInfo(className, methodName);
		if(methodInfo == null) {
			methodInfo = new MethodInfo();
			methodInfo.setParamCount(method.getParameterCount());
			methodInfo.setNames(discover.getArgsNames(method));
			methodInfo.setParamTypes(method.getParameterTypes());
			methodInfo.setReturnType(method.getReturnType());
			methodInfo.setGenericReturnType(method.getGenericReturnType());
			SQLParser.addMethodInfo(className, methodName, methodInfo);
		}
		
		FinalSQL finalSQL = SQLParser.parse(sql, methodInfo, args); // 根据传入参数动态解析表达式
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		String action = sql.getAction();
		Object result = null;
		if(action.equals(DynamicSQL.INSERT)) {
			result = executor.insert(finalSQL);
		} else if(action.equals(DynamicSQL.DELETE)) {
			result = executor.delete(finalSQL);
		} else if(action.equals(DynamicSQL.UPDATE)) {
			result = executor.update(finalSQL);
		} else if(action.equals(DynamicSQL.SELECT)) {
			result = select(executor, finalSQL, sql, methodInfo);
		}
		
		// Object result = method.invoke(object, args); // 
		return result;
	}
	
	private Object select(SQLExecutor executor, FinalSQL finalSQL, DynamicSQL sql, MethodInfo methodInfo) throws ClassNotFoundException {
		Object result = null;
		List relations = sql.getRelations();
		ResultSet resultSet = executor.query(finalSQL);
		Class returnType = methodInfo.getReturnType();
		if(ObjectUtils.isPrimitivePlus(returnType)) {
			result = ResultSetUtils.convertToOne(resultSet, returnType);
			
		} else if(BaseEntity.class.isAssignableFrom(returnType)) {
			BaseEntity entity = this.returnEntity(methodInfo, resultSet, relations);
			result = entity;
			
			
		} else if(Map.class.isAssignableFrom(returnType)) {
			Map map = this.returnMap(methodInfo, resultSet, relations);
			result = map;
			
		} else if(Set.class.isAssignableFrom(returnType)) {
			result = this.returnSet(methodInfo, resultSet, relations);
			
		} else if(List.class.isAssignableFrom(returnType)) {
			result = this.returnList(methodInfo, resultSet, relations);
			
		} else if(returnType.isArray()) {
			result = this.returnArray(methodInfo, resultSet, relations);
			
		} else {
			throw new ResultSetParserException("暂不支持的返回类型:" + returnType);
		}
		return result;
	}
	
	private void joinSelect(List relations, BaseEntity entity, SQLExecutor executor){
		for (Relation relation : relations) {
			String type = relation.getType();
			String property = relation.getProperty();
			Class propertyType = entity.getFieldType(property);
			if(RelationType.oneToOne.value.equals(type)) {
				ResultMap map = executor.findFirst(relation.getSql(), entity);
				if(propertyType == null) {
					entity.put(property, map);
				} else {
					entity.set(property, BaseEntity.toEntity(map, propertyType));
				}
			} else if(RelationType.oneToMany.value.equals(type)) {
				List> list = executor.findList(relation.getSql(), entity);
				if(propertyType == null) {
					entity.put(property, list);
				} else {
					List newList = new ArrayList();
					for (ResultMap map : list) {
						newList.add(BaseEntity.toEntity(map, propertyType));
					}
					entity.set(property, newList);
				}
			}
		}
	}
	
	private void joinSelect(List relations, Map map, SQLExecutor executor){
		for (Relation relation : relations) {
			String type = relation.getType();
			String property = relation.getProperty();
			if(RelationType.oneToOne.value.equals(type)) {
				ResultMap resultMap = executor.findFirst(relation.getSql(), map);
				map.put(property, resultMap);
			} else if(RelationType.oneToMany.value.equals(type)) {
				List> list = executor.findList(relation.getSql(), map);
				map.put(property, list);
			}
		}
	}
	
	private BaseEntity returnEntity(MethodInfo methodInfo, ResultSet resultSet, List relations) {
		Class returnType = methodInfo.getReturnType();
		ResultMap resultMap = ResultSetUtils.convertToMap(resultSet);
		BaseEntity entity = (BaseEntity) BaseEntity.toEntity(resultMap, returnType);
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		this.joinSelect(relations, entity, executor);
		return entity;
	}
	
	private Map returnMap(MethodInfo methodInfo, ResultSet resultSet, List relations) throws ClassNotFoundException{
		Map map = null;
		Class returnType = methodInfo.getReturnType();
		Type genericReturnType = methodInfo.getGenericReturnType();
		ResultMap resultMap = ResultSetUtils.convertToMap(resultSet);
		if(genericReturnType instanceof ParameterizedType){
			Type[] parameterizedTypes = ((ParameterizedType) genericReturnType).getActualTypeArguments();
			String keyType = parameterizedTypes[0].getTypeName();
			String valType = parameterizedTypes[1].getTypeName();
			if(!keyType.equals("java.lang.String")){
				throw new ResultSetParserException("不支持的返回类型:" + returnType);
			}
			Class type = Class.forName(valType);
			Set> set = resultMap.entrySet();
			for (Entry entry : set) {
				Object value = entry.getValue();
				resultMap.put(entry.getKey(), ObjectUtils.convert(value, type));
			}
		} else {
			map = resultMap;
			if(HashMap.class.isAssignableFrom(returnType)) {
				map = new HashMap(resultMap);
			} else if(TreeMap.class.isAssignableFrom(returnType)) {
				map = new TreeMap(resultMap);
			}
		}
		
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		this.joinSelect(relations, map, executor);
		return map;
	}
	
	private Object returnSet(MethodInfo methodInfo, ResultSet resultSet, List relations) throws ClassNotFoundException{
		Object result = null;
		Class returnType = methodInfo.getReturnType();
		Type genericReturnType = methodInfo.getGenericReturnType();
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		if(genericReturnType instanceof ParameterizedType){
			Type[] parameterizedTypes = ((ParameterizedType) genericReturnType).getActualTypeArguments();
			String type = parameterizedTypes[0].getTypeName();
			Class clazz = Class.forName(type);
			if(ObjectUtils.isPrimitivePlus(clazz)){
				result = ResultSetUtils.convertToSingleSet(resultSet, clazz);
			} else {
				Set> set = ResultSetUtils.convertToSet(resultSet);
				if(BaseEntity.class.isAssignableFrom(clazz)){
					Set newSet = new HashSet();
					for (ResultMap map : set) {
						BaseEntity entity = (BaseEntity) BaseEntity.toEntity(map, clazz);
						this.joinSelect(relations, entity, executor);
						newSet.add(entity);
					}
					result = newSet;
				} else if(Map.class.isAssignableFrom(clazz)){
					result = set;
				} else {
					throw new ResultSetParserException("不支持的返回类型:" + returnType);
				}
			}
		} else {
			Set> set = ResultSetUtils.convertToSet(resultSet);
			for (ResultMap map : set) {
				this.joinSelect(relations, map, executor);
			}
			result = set;
			if(HashSet.class.isAssignableFrom(returnType)) {
				result = new HashSet(set);
			}
			if(TreeSet.class.isAssignableFrom(returnType)) {
				result = new TreeSet(set);
			}
		}
		return result;
	}
	
	private Object returnList(MethodInfo methodInfo, ResultSet resultSet, List relations) throws ClassNotFoundException{
		Object result = null;
		Class returnType = methodInfo.getReturnType();
		Type genericReturnType = methodInfo.getGenericReturnType();
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		if(genericReturnType instanceof ParameterizedType){
			Type[] parameterizedTypes = ((ParameterizedType) genericReturnType).getActualTypeArguments();
			String type = parameterizedTypes[0].getTypeName();
			Class clazz = Class.forName(type);
			if(ObjectUtils.isPrimitivePlus(clazz)){
				result = ResultSetUtils.convertToSingleList(resultSet, clazz);
			} else {
				List> list = ResultSetUtils.convertToList(resultSet);
				if(BaseEntity.class.isAssignableFrom(clazz)){
					List newList = new ArrayList();
					for (ResultMap map : list) {
						BaseEntity entity = (BaseEntity) BaseEntity.toEntity(map, clazz);
						this.joinSelect(relations, entity, executor);
						newList.add(entity);
					}
					result = newList;
				} else if(Map.class.isAssignableFrom(clazz)){
					result = list;
				} else {
					throw new ResultSetParserException("不支持的返回类型:" + genericReturnType);
				}
			}
		} else {
			List> list = ResultSetUtils.convertToList(resultSet);
			for (ResultMap map : list) {
				this.joinSelect(relations, map, executor);
			}
			result = list;
			if(ArrayList.class.isAssignableFrom(returnType)) {
				result = new ArrayList(list);
			}
			if(LinkedList.class.isAssignableFrom(returnType)) {
				result = new LinkedList(list);
			}
		}
		return result;
	}
	
	private Object returnArray(MethodInfo methodInfo, ResultSet resultSet, List relations) {
		Object result = null;
		Class returnType = methodInfo.getReturnType();
		Class componentType = returnType.getComponentType();
		SQLExecutor executor = ExecutorFactory.createSQLExcutor();
		if(ObjectUtils.isPrimitivePlus(componentType)){
			List list = ResultSetUtils.convertToSingleList(resultSet, componentType);
			result = list.toArray();
		} else {
			List>  list = ResultSetUtils.convertToList(resultSet);
			if(BaseEntity.class.isAssignableFrom(componentType)) {
				Object array = Array.newInstance(componentType, list.size());
				for (int i = 0; i < list.size(); i++) {
					BaseEntity entity = (BaseEntity) BaseEntity.toEntity(list.get(i), componentType);
					this.joinSelect(relations, entity, executor);
					Array.set(array, i, entity);
				}
				result = array;
			} else if(Map.class.isAssignableFrom(componentType)) {
				for (ResultMap map : list) {
					this.joinSelect(relations, map, executor);
				}
				result = list.toArray();
			} else {
				throw new ResultSetParserException("不支持的数组返回类型:" + componentType);
			}
		}
		return result;
	}
}