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 }