Java tutorial
/* * Copyright 2009-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License i distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gzj.tulip.jade.statement; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import com.gzj.tulip.jade.dataaccess.DataAccess; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.RowMapper; import com.gzj.tulip.jade.annotation.SQLType; import com.gzj.tulip.jade.dataaccess.DataAccessFactory; /** * SELECT * * @author [qieqie.wang@gmail.com] * @author [in355hz@gmail.com] */ @SuppressWarnings({ "rawtypes", "unchecked" }) public class SelectQuerier implements Querier { private final RowMapper rowMapper; private final Class<?> returnType; private final DataAccessFactory dataAccessFactory; private final ResultConverter converter; public SelectQuerier(DataAccessFactory dataAccessFactory, StatementMetaData metaData, RowMapper rowMapper) { this.dataAccessFactory = dataAccessFactory; this.returnType = metaData.getReturnType(); this.rowMapper = rowMapper; this.converter = makeResultConveter(); } @Override public Object execute(SQLType sqlType, StatementRuntime... runtimes) { return execute(sqlType, (StatementRuntime) runtimes[0]); } public Object execute(SQLType sqlType, StatementRuntime runtime) { DataAccess dataAccess = dataAccessFactory.getDataAccess(// runtime.getMetaData(), runtime.getAttributes()); // List<?> listResult = dataAccess.select(runtime.getSQL(), runtime.getArgs(), rowMapper); return converter.convert(runtime, listResult); } protected ResultConverter makeResultConveter() { ResultConverter converter; if (List.class == returnType || Collection.class == returnType || Iterable.class == returnType) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { return listResult; } }; } else if (ArrayList.class == returnType) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { return new ArrayList(listResult); } }; } else if (LinkedList.class == returnType) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { return new LinkedList(listResult); } }; } else if (Set.class == returnType || HashSet.class == returnType) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { return new HashSet(listResult); } }; } else if (Collection.class.isAssignableFrom(returnType)) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { Collection listToReturn; try { listToReturn = (Collection) returnType.newInstance(); } catch (Exception e) { throw new Error("error to create instance of " + returnType.getName()); } listToReturn.addAll(listResult); return listToReturn; } }; } else if (Iterator.class == returnType) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { return listResult.iterator(); } }; } else if (returnType.isArray() && byte[].class != returnType) { if (returnType.getComponentType().isPrimitive()) { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { Object array = Array.newInstance(returnType.getComponentType(), listResult.size()); int len = listResult.size(); for (int i = 0; i < len; i++) { Array.set(array, i, listResult.get(i)); } return array; } }; } else { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { Object array = Array.newInstance(returnType.getComponentType(), listResult.size()); return listResult.toArray((Object[]) array); } }; } } else if (Map.class == returnType || HashMap.class == returnType) { converter = new MapConverter() { @Override protected Map creatMap(StatementRuntime runtime) { return new HashMap(); } }; } else if (Hashtable.class == returnType) { converter = new MapConverter() { @Override protected Map creatMap(StatementRuntime runtime) { return new Hashtable(); } }; } else if (Map.class.isAssignableFrom(returnType)) { converter = new MapConverter() { @Override protected Map creatMap(StatementRuntime runtime) { try { return (Map) returnType.newInstance(); } catch (Exception e) { throw new Error("error to create instance of " + returnType.getName()); } } }; } // else { converter = new ResultConverter() { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { final int sizeResult = listResult.size(); if (sizeResult == 1) { // ? Bean?Boolean return listResult.get(0); } else if (sizeResult == 0) { // null if (returnType.isPrimitive()) { String msg = "Incorrect result size: expected 1, actual " + sizeResult + ": " + runtime.getMetaData(); throw new EmptyResultDataAccessException(msg, 1); } else { return null; } } else { // IncorrectResultSizeDataAccessException String msg = "Incorrect result size: expected 0 or 1, actual " + sizeResult + ": " + runtime.getMetaData(); throw new IncorrectResultSizeDataAccessException(msg, 1, sizeResult); } } }; } return converter; } /** * {@link ResultConverter} SELECT?ListDAO? * <p> * */ static interface ResultConverter { Object convert(StatementRuntime runtime, List<?> listResult); } static abstract class MapConverter implements ResultConverter { @Override public Object convert(StatementRuntime runtime, List<?> listResult) { Map map = creatMap(runtime); for (Object obj : listResult) { if (obj == null) { continue; } Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj; if (map.getClass() == Hashtable.class && entry.getKey() == null) { continue; } map.put(entry.getKey(), entry.getValue()); } return map; } protected abstract Map creatMap(StatementRuntime runtime); } }