View Javadoc

    1   package sharin.sql.runner.processor;
    2
    3   import java.math.BigDecimal;
    4   import java.sql.Date;
    5   import java.sql.ResultSet;
    6   import java.sql.ResultSetMetaData;
    7   import java.sql.Time;
    8   import java.sql.Timestamp;
    9   import java.util.HashMap;
    10  import java.util.Map;
    11
    12  import sharin.sql.runner.ColumnConverter;
    13  import sharin.sql.runner.ResultSetProcessor;
    14  import sharin.sql.runner.converter.BigDecimalColumnConverter;
    15  import sharin.sql.runner.converter.BooleanColumnConverter;
    16  import sharin.sql.runner.converter.ByteColumnConverter;
    17  import sharin.sql.runner.converter.BytesColumnConverter;
    18  import sharin.sql.runner.converter.DateColumnConverter;
    19  import sharin.sql.runner.converter.DoubleColumnConverter;
    20  import sharin.sql.runner.converter.FloatColumnConverter;
    21  import sharin.sql.runner.converter.IntegerColumnConverter;
    22  import sharin.sql.runner.converter.LongColumnConverter;
    23  import sharin.sql.runner.converter.ObjectColumnConverter;
    24  import sharin.sql.runner.converter.PrimitiveBooleanColumnConverter;
    25  import sharin.sql.runner.converter.PrimitiveByteColumnConverter;
    26  import sharin.sql.runner.converter.PrimitiveDoubleColumnConverter;
    27  import sharin.sql.runner.converter.PrimitiveFloatColumnConverter;
    28  import sharin.sql.runner.converter.PrimitiveIntColumnConverter;
    29  import sharin.sql.runner.converter.PrimitiveLongColumnConverter;
    30  import sharin.sql.runner.converter.PrimitiveShortColumnConverter;
    31  import sharin.sql.runner.converter.ShortColumnConverter;
    32  import sharin.sql.runner.converter.StringColumnConverter;
    33  import sharin.sql.runner.converter.TimeColumnConverter;
    34  import sharin.sql.runner.converter.TimestampColumnConverter;
    35  import sharin.util.PropertyUtils;
    36  import sharin.util.ReflectUtils;
    37  import sharin.util.SqlUtils;
    38
    39  public class BeanResultSetProcessor implements ResultSetProcessor {
    40
    41      private static final Map<Class<?>, ColumnConverter> defaultColumnConverterMap;
    42
    43      static {
    44          Map<Class<?>, ColumnConverter> map = new HashMap<Class<?>, ColumnConverter>();
    45
    46          map.put(boolean.class, new PrimitiveBooleanColumnConverter());
    47          map.put(byte.class, new PrimitiveByteColumnConverter());
    48          map.put(double.class, new PrimitiveDoubleColumnConverter());
    49          map.put(float.class, new PrimitiveFloatColumnConverter());
    50          map.put(int.class, new PrimitiveIntColumnConverter());
    51          map.put(long.class, new PrimitiveLongColumnConverter());
    52          map.put(short.class, new PrimitiveShortColumnConverter());
    53
    54          map.put(BigDecimal.class, new BigDecimalColumnConverter());
    55          map.put(Boolean.class, new BooleanColumnConverter());
    56          map.put(Byte.class, new ByteColumnConverter());
    57          map.put(byte[].class, new BytesColumnConverter());
    58          map.put(Date.class, new DateColumnConverter());
    59          map.put(Double.class, new DoubleColumnConverter());
    60          map.put(Float.class, new FloatColumnConverter());
    61          map.put(Integer.class, new IntegerColumnConverter());
    62          map.put(Long.class, new LongColumnConverter());
    63          map.put(Object.class, new ObjectColumnConverter());
    64          map.put(Short.class, new ShortColumnConverter());
    65          map.put(String.class, new StringColumnConverter());
    66          map.put(Time.class, new TimeColumnConverter());
    67          map.put(Timestamp.class, new TimestampColumnConverter());
    68
    69          defaultColumnConverterMap = map;
    70      }
    71
    72      private final Class<?> beanClass;
    73
    74      private final Map<Class<?>, ColumnConverter> columnConverterMap;
    75
    76      private final ColumnConverter objectColumnConverter;
    77
    78      public BeanResultSetProcessor(Class<?> beanClass) {
    79          this(beanClass, null);
    80      }
    81
    82      public BeanResultSetProcessor(Class<?> beanClass,
    83              Map<Class<?>, ColumnConverter> columnConverterMap) {
    84
    85          this.beanClass = beanClass;
    86
    87          Map<Class<?>, ColumnConverter> map = new HashMap<Class<?>, ColumnConverter>();
    88          map.putAll(defaultColumnConverterMap);
    89
    90          if (columnConverterMap != null) {
    91              map.putAll(columnConverterMap);
    92          }
    93
    94          this.columnConverterMap = map;
    95          this.objectColumnConverter = map.get(Object.class);
    96      }
    97
    98      public Object prepare(ResultSet rs) {
    99          ResultSetMetaData metaData = SqlUtils.getMetaData(rs);
    100         int columnCount = SqlUtils.getColumnCount(metaData);
    101         String[] columnLabels = new String[columnCount];
    102         ColumnConverter[] columnConverters = new ColumnConverter[columnCount];
    103
    104         for (int i = 0; i < columnCount; i++) {
    105             columnLabels[i] = SqlUtils.getColumnLabel(metaData, i + 1);
    106             Class<?> type = PropertyUtils.getNestedPropertyType(beanClass,
    107                     columnLabels[i]);
    108
    109             if (type != null) {
    110                 columnConverters[i] = columnConverterMap.get(type);
    111             }
    112
    113             if (columnConverters[i] == null) {
    114                 columnConverters[i] = objectColumnConverter;
    115             }
    116         }
    117
    118         Map<String, Object> mapContext = new HashMap<String, Object>();
    119         mapContext.put("columnLabels", columnLabels);
    120         mapContext.put("columnConverters", columnConverters);
    121         return mapContext;
    122     }
    123
    124     @SuppressWarnings("unchecked")
    125     public Object process(ResultSet rs, Object context) {
    126         Map<String, Object> mapContext = (Map<String, Object>) context;
    127         String[] columnLabels = (String[]) mapContext.get("columnLabels");
    128         ColumnConverter[] columnConverters = (ColumnConverter[]) mapContext
    129                 .get("columnConverters");
    130         Object result = ReflectUtils.newInstance(beanClass);
    131
    132         for (int i = 0; i < columnLabels.length; i++) {
    133             Object value = columnConverters[i].convert(rs, i + 1);
    134             PropertyUtils
    135                     .setNestedPropertyValue(result, columnLabels[i], value);
    136         }
    137
    138         return result;
    139     }
    140 }