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

net.paoding.rose.jade.rowmapper.DefaultRowMapperFactory Maven / Gradle / Ivy

/*
 * 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 net.paoding.rose.jade.annotation.RowHandler;
import net.paoding.rose.jade.annotation.StatementRowMapper;
import net.paoding.rose.jade.excetion.JadeException;
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;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

/**
 * 支持DAO方法返回类型:
 * 

*

    *
  • int、long等primitive:期望返回单列、1行
  • *
  • Integer、Long等包装类型的:期望返回单列、0行或1行
  • *
  • String、BigDecimal:期望返回单列,0行或1行
  • *
  • java.util.Date及其子类:期望返回单列,0行或1行
  • *
  • byte[]:期望返回单行、单列;列类型可转化为byte[]类型(比如blob类型)
  • *
  • Blob、Clob:期望返回单,0行或1行
  • *
  • 数组(int[]、String[]等):期望返回单列,多行;
  • *
  • 数组(User[]等):期望返回多列,多行;
  • *
  • 集合(List<Integer>、Set<String>等): 期望返回单列,多行;
  • *
  • 集合(List<User>、Set<User>等): 期望返回单列,多行;
  • *
  • 映射(Map<String, Date>): 期望返回2列,多行
  • *
  • 映射(Map<String, User>): 期望返回多列,多行
  • *
  • 映射(Map<String, String[]>): 期望返回多列,多行
  • *
      * @author 王志亮 [[email protected]] * @author 廖涵 [[email protected]] */ @SuppressWarnings({"rawtypes", "unchecked"}) public class DefaultRowMapperFactory implements RowMapperFactory { private static Log logger = LogFactory.getLog(RowMapperFactory.class); private Map rowMappers = new HashMap(); @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); } if (rowMapper instanceof StatementRowMapper) { ((StatementRowMapper) rowMapper).init(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; // 返回单列的查询的(或者返回只有2列的Map类型查询的) if (TypeUtils.isColumnType(rowType)) { if (Map.class.isAssignableFrom(returnClassType)) { 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) || rowHandler.checkColumns(); boolean checkProperties = (rowHandler != null) && rowHandler.checkProperties(); boolean toOptional = rowType == Optional.class; boolean toStream = rowType == Stream.class; Class[] genericReturnTypes = modifier.getGenericReturnTypes(); StringBuilder key = new StringBuilder(rowType.getName()); key.append("[checkColumns=").append(checkColumns).append("&checkProperties=").append(checkProperties); if (genericReturnTypes != null && genericReturnTypes.length == 1) { key.append("&genericReturnTypes=").append(genericReturnTypes[0].getTypeName()); } rowMapper = rowMappers.get(key.append("]").toString()); if (rowMapper == null) { if (toOptional) { if (genericReturnTypes == null || genericReturnTypes.length != 1) { throw new JadeException("option generic paradigm [T] is null or length not equal to 1"); } rowType = genericReturnTypes[0]; } else if (toStream) { if (genericReturnTypes == null || genericReturnTypes.length != 1) { throw new JadeException("stream generic paradigm [T] is null or length not equal to 1"); } rowType = genericReturnTypes[0]; } // jade's BeanPropertyRowMapper here rowMapper = new BeanPropertyRowMapper(rowType, checkColumns, checkProperties, toOptional); rowMappers.put(key.toString(), rowMapper); } } // 如果DAO方法最终返回的是Map,rowMapper要返回Map.Entry对象 if (Map.class.isAssignableFrom(returnClassType)) { 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.getReturnType(); if (Collection.class.isAssignableFrom(returnClassType)// || Iterable.class == returnClassType // || Iterator.class == returnClassType) { return getRowTypeFromCollectionType(statementMetaData, returnClassType); } // else if (Map.class.isAssignableFrom(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 值元素类型 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/ArrayList/LinkedList, CollectionIterable/Iterator, Set/HashSet if ((returnClassType != List.class) && (returnClassType != ArrayList.class) && (returnClassType != LinkedList.class)// && (returnClassType != Collection.class) && (returnClassType != Iterable.class) && (returnClassType != Iterator.class) && (returnClassType != Set.class) && (returnClassType != HashSet.class) ) { throw new IllegalArgumentException("error collection type " + returnClassType.getName() + "; only support List/ArrayList/LinkedList, CollectionIterable/Iterator, Set/HashSet"); } // 获取集合元素类型 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; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy