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 net.paoding.rose.jade.rowmapper; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import net.paoding.rose.jade.annotation.RowHandler; import net.paoding.rose.jade.statement.StatementMetaData; import org.apache.commons.lang.ClassUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanInstantiationException; import org.springframework.jdbc.core.ColumnMapRowMapper; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.SingleColumnRowMapper; /** * ?DAO * <p> * <ul> * <li>int?longprimitive??1</li> * <li>Integer?Long??01</li> * <li>String?BigDecimal?01</li> * <li>java.util.Date???01</li> * <li>byte[]????byte[](blob)</li> * <li>Blob?Clob?01</li> * <li><code>(int[]?String[])?</li> * <li>(User[])</li> * <li>?(List<Integer>?Set<String>): ?</li> * <li>?(List<User>?Set<User>): ?</li> * <li>(Map<String, Date>): 2</li> * <li>(Map<String, User>): </li> * <li>(Map<String, String[]>): </li> * <ul> * * @author [qieqie.wang@gmail.com] * @author [in355hz@gmail.com] */ public class DefaultRowMapperFactory implements RowMapperFactory { private static Log logger = LogFactory.getLog(RowMapperFactory.class); private Map<String, RowMapper> rowMappers = new HashMap<String, RowMapper>(); @Override public RowMapper getRowMapper(StatementMetaData modifier) { RowHandler rowHandler = modifier.getAnnotation(RowHandler.class); if (rowHandler != null) { if (rowHandler.rowMapper() != RowHandler.ByDefault.class) { try { RowMapper rowMapper = rowHandler.rowMapper().newInstance(); if (logger.isInfoEnabled()) { logger.info("using rowMapper " + rowMapper + " for " + modifier); } return rowMapper; } catch (Exception ex) { throw new BeanInstantiationException(rowHandler.rowMapper(), ex.getMessage(), ex); } } } // Class<?> returnClassType = modifier.getMethod().getReturnType(); Class<?> rowType = getRowType(modifier); // BUGFIX: SingleColumnRowMapper ? Primitive Type if (rowType.isPrimitive()) { rowType = ClassUtils.primitiveToWrapper(rowType); } // ? RowMapper RowMapper rowMapper; // ?(?2Map) if (TypeUtils.isColumnType(rowType)) { if (returnClassType == Map.class) { rowMapper = new MapEntryColumnRowMapper(modifier, rowType); } else { rowMapper = new SingleColumnRowMapper(rowType); } } // Bean?????? else { if (rowType == Map.class) { rowMapper = new ColumnMapRowMapper(); } else if (rowType.isArray()) { rowMapper = new ArrayRowMapper(rowType); } else if ((rowType == List.class) || (rowType == Collection.class)) { rowMapper = new ListRowMapper(modifier); } else if (rowType == Set.class) { rowMapper = new SetRowMapper(modifier); } else { boolean checkColumns = (rowHandler == null) ? true : rowHandler.checkColumns(); boolean checkProperties = (rowHandler == null) ? false : rowHandler.checkProperties(); String key = rowType.getName() + "[checkColumns=" + checkColumns + "&checkProperties=" + checkProperties + "]"; rowMapper = rowMappers.get(key); if (rowMapper == null) { rowMapper = new BeanPropertyRowMapper(rowType, checkColumns, checkProperties); // jade's BeanPropertyRowMapper here rowMappers.put(key, rowMapper); } } // DAOMaprowMapper?Map.Entry if (returnClassType == Map.class) { rowMapper = new MapEntryRowMapper(modifier, rowMapper); } } if (logger.isInfoEnabled()) { logger.info("using rowMapper " + rowMapper + " for " + modifier); } return rowMapper; } // ? private static Class<?> getRowType(StatementMetaData statementMetaData) { Class<?> returnClassType = statementMetaData.getMethod().getReturnType(); if (Collection.class.isAssignableFrom(returnClassType)) { return getRowTypeFromCollectionType(statementMetaData, returnClassType); } else if (Map.class == returnClassType) { return getRowTypeFromMapType(statementMetaData, returnClassType); } else if (returnClassType.isArray() && returnClassType != byte[].class) { // , ?? return returnClassType.getComponentType(); } // DAO? return returnClassType; } private static Class<?> getRowTypeFromMapType(StatementMetaData modifier, Class<?> returnClassType) { Class<?> rowType; // ? Map<K, V> Class<?>[] genericTypes = modifier.getGenericReturnTypes(); if (genericTypes.length != 2) { throw new IllegalArgumentException("the returned generic type '" + returnClassType.getName() + "' should has two actual type parameters."); } rowType = genericTypes[1]; // ? V return rowType; } private static Class<?> getRowTypeFromCollectionType(StatementMetaData modifier, Class<?> returnClassType) { Class<?> rowType; // ? List / Collection / Set if ((returnClassType != List.class) && (returnClassType != Collection.class) && (returnClassType != Set.class)) { throw new IllegalArgumentException( "error collection type " + returnClassType.getName() + "; only support List, Set, Collection"); } // ?? Class<?>[] genericTypes = modifier.getGenericReturnTypes(); if (genericTypes.length != 1) { throw new IllegalArgumentException("the returned generic type '" + returnClassType.getName() + "' should has a actual type parameter."); } rowType = genericTypes[0]; return rowType; } }