Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.90 KB | None | 0 0
  1. package com.github.zqxin;
  2.  
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.ParameterizedType;
  6. import java.sql.ResultSet;
  7. import java.sql.ResultSetMetaData;
  8. import java.util.ArrayList;
  9. import java.util.Collection;
  10. import java.util.HashMap;
  11. import java.util.HashSet;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.Set;
  15.  
  16. public class ResultSetObjectMapper<T> {
  17.  
  18. private String columnPrefix;
  19. private JoinOn joinOn;
  20. private ResultSet resultSet;
  21. private Class<? extends T> resultType;
  22.  
  23. public ResultSetObjectMapper(
  24. ResultSet aResultSet,
  25. Class<T> aResultType,
  26. JoinOn aJoinOn) {
  27.  
  28. super();
  29.  
  30. this.joinOn = aJoinOn;
  31. this.resultSet = aResultSet;
  32. this.resultType = aResultType;
  33. }
  34.  
  35. public ResultSetObjectMapper(
  36. ResultSet aResultSet,
  37. Class<? extends T> aResultType,
  38. String aColumnPrefix,
  39. JoinOn aJoinOn) {
  40.  
  41. super();
  42.  
  43. this.columnPrefix = aColumnPrefix;
  44. this.joinOn = aJoinOn;
  45. this.resultSet = aResultSet;
  46. this.resultType = aResultType;
  47. }
  48.  
  49. public T mapResultToType() {
  50. T object = this.createFrom(this.resultType());
  51.  
  52. Set<String> associationsToMap = new HashSet<String>();
  53.  
  54. Field[] fields = this.resultType().getDeclaredFields();
  55.  
  56. for (Field field : fields) {
  57. String columnName = this.fieldNameToColumnName(field.getName());
  58.  
  59. if (this.hasColumn(this.resultSet(), columnName)) {
  60. Object columnValue = this.columnValueFrom(columnName, field.getType());
  61.  
  62. this.joinOn().saveCurrentLeftQualifier(columnName, columnValue);
  63.  
  64. try {
  65. field.setAccessible(true);
  66. field.set(object, columnValue);
  67. } catch (Exception e) {
  68. throw new IllegalStateException(
  69. "Cannot map to: "
  70. + this.resultType.getSimpleName()
  71. + "#"
  72. + columnName);
  73. }
  74. } else {
  75. String objectPrefix = this.toObjectPrefix(columnName);
  76.  
  77. if (!associationsToMap.contains(objectPrefix) &&
  78. this.hasAssociation(this.resultSet(), objectPrefix)) {
  79.  
  80. associationsToMap.add(field.getName());
  81. }
  82. }
  83. }
  84.  
  85. if (!associationsToMap.isEmpty()) {
  86. this.mapAssociations(object, this.resultSet(), associationsToMap);
  87. }
  88.  
  89. return object;
  90. }
  91.  
  92. private String columnPrefix() {
  93. return this.columnPrefix;
  94. }
  95.  
  96. private boolean hasColumnPrefix() {
  97. return this.columnPrefix != null;
  98. }
  99.  
  100. private Object columnValueFrom(String aColumnName, Class<?> aType) {
  101.  
  102. Object value = null;
  103. String tempStr = null;
  104.  
  105. try {
  106. String typeName = aType.getName();
  107.  
  108. if (aType.isPrimitive()) {
  109.  
  110. // boolean, byte, char, short, int, long, float, double
  111.  
  112. if (typeName.equals("int")) {
  113. value = new Integer(this.resultSet().getInt(aColumnName));
  114. } else if (typeName.equals("long")) {
  115. value = new Long(this.resultSet().getLong(aColumnName));
  116. } else if (typeName.equals("boolean")) {
  117. int oneOrZero = this.resultSet().getInt(aColumnName);
  118. value = oneOrZero == 1 ? Boolean.TRUE : Boolean.FALSE;
  119. } else if (typeName.equals("short")) {
  120. value = new Short(this.resultSet().getShort(aColumnName));
  121. } else if (typeName.equals("float")) {
  122. value = new Float(this.resultSet().getFloat(aColumnName));
  123. } else if (typeName.equals("double")) {
  124. value = new Double(this.resultSet().getDouble(aColumnName));
  125. } else if (typeName.equals("byte")) {
  126. value = new Byte(this.resultSet().getByte(aColumnName));
  127. } else if (typeName.equals("char")) {
  128. String charStr = this.resultSet().getString(aColumnName);
  129. if (charStr == null) {
  130. value = new Character((char) 0);
  131. } else {
  132. value = charStr.charAt(0);
  133. }
  134. }
  135.  
  136. } else {
  137. if (typeName.equals("java.lang.String")) {
  138. value = this.resultSet().getString(aColumnName);
  139. } else if (typeName.equals("java.lang.Integer")) {
  140. tempStr = this.resultSet().getString(aColumnName);
  141. value = tempStr == null ? null: Integer.parseInt(tempStr);
  142. } else if (typeName.equals("java.lang.Long")) {
  143. tempStr = this.resultSet().getString(aColumnName);
  144. value = tempStr == null ? null : Long.parseLong(tempStr);
  145. } else if (typeName.equals("java.lang.Boolean")) {
  146. int oneOrZero = this.resultSet().getInt(aColumnName);
  147. value = oneOrZero == 1 ? Boolean.TRUE : Boolean.FALSE;
  148. } else if (typeName.equals("java.util.Date")) {
  149. java.sql.Timestamp timestamp = this.resultSet().getTimestamp(aColumnName);
  150. if (timestamp != null) {
  151. value = new java.util.Date(timestamp.getTime() + timestamp.getNanos());
  152. }
  153. } else if (typeName.equals("java.lang.Short")) {
  154. tempStr = this.resultSet().getString(aColumnName);
  155. value = tempStr == null ? null: Short.parseShort(tempStr);
  156. } else if (typeName.equals("java.lang.Float")) {
  157. tempStr = this.resultSet().getString(aColumnName);
  158. value = tempStr == null ? null : Float.parseFloat(tempStr);
  159. } else if (typeName.equals("java.lang.Double")) {
  160. tempStr = this.resultSet().getString(aColumnName);
  161. value = tempStr == null ? null : Double.parseDouble(tempStr);
  162. }
  163. }
  164.  
  165. } catch (Exception e) {
  166. throw new IllegalArgumentException(
  167. "Cannot map "
  168. + aColumnName
  169. + " because: "
  170. + e.getMessage(),
  171. e);
  172. }
  173.  
  174. return value;
  175. }
  176.  
  177. private Collection<Object> createCollectionFrom(Class<?> aType) {
  178.  
  179. Collection<Object> newCollection = null;
  180.  
  181. if (List.class.isAssignableFrom(aType)) {
  182. newCollection = new ArrayList<Object>();
  183. } else if (Set.class.isAssignableFrom(aType)) {
  184. newCollection = new HashSet<Object>();
  185. }
  186.  
  187. return newCollection;
  188. }
  189.  
  190. private T createFrom(Class<? extends T> aClass) {
  191. T object = null;
  192.  
  193. try {
  194. Constructor<? extends T> ctor = aClass.getDeclaredConstructor();
  195.  
  196. object = ctor.newInstance();
  197.  
  198. } catch (Exception e) {
  199. throw new IllegalArgumentException("Cannot create instance of: " + aClass.getName());
  200. }
  201.  
  202. return object;
  203. }
  204.  
  205. private String fieldNameToColumnName(String aFieldName) {
  206. StringBuffer buf = new StringBuffer();
  207.  
  208. if (this.hasColumnPrefix()) {
  209. buf.append(this.columnPrefix());
  210. }
  211.  
  212. for (char ch : aFieldName.toCharArray()) {
  213. if (Character.isAlphabetic(ch) && Character.isUpperCase(ch)) {
  214. buf.append('_').append(Character.toLowerCase(ch));
  215. } else {
  216. buf.append(ch);
  217. }
  218. }
  219.  
  220. return buf.toString();
  221. }
  222.  
  223. private boolean hasAssociation(
  224. ResultSet aResultSet,
  225. String anObjectPrefix) {
  226.  
  227. try {
  228. ResultSetMetaData metaData = aResultSet.getMetaData();
  229. int totalColumns = metaData.getColumnCount();
  230.  
  231. for (int idx = 1; idx <= totalColumns; ++idx) {
  232. String columnName = metaData.getColumnLabel(idx);
  233.  
  234. if (columnName.startsWith(anObjectPrefix) &&
  235. this.joinOn().isJoinedOn(aResultSet)) {
  236.  
  237. return true;
  238. }
  239. }
  240.  
  241. } catch (Exception e) {
  242. throw new IllegalStateException(
  243. "Cannot read result metadata because: "
  244. + e.getMessage(),
  245. e);
  246. }
  247.  
  248. return false;
  249. }
  250.  
  251. private boolean hasColumn(ResultSet aResultSet, String aColumnName) {
  252. try {
  253. aResultSet.findColumn(aColumnName);
  254.  
  255. return true;
  256.  
  257. } catch (Exception e) {
  258. return false;
  259. }
  260. }
  261.  
  262. private JoinOn joinOn() {
  263. return this.joinOn;
  264. }
  265.  
  266. private void mapAssociations(
  267. T anObject,
  268. ResultSet aResultSet,
  269. Set<String> anAssociationsToMap) {
  270.  
  271. Map<String, Collection<Object>> mappedCollections =
  272. new HashMap<String, Collection<Object>>();
  273.  
  274. String currentAssociationName = null;
  275.  
  276. try {
  277. for (boolean hasResult = true; hasResult; hasResult = aResultSet.next()) {
  278.  
  279. if (!this.joinOn().hasCurrentLeftQualifier(aResultSet)) {
  280. aResultSet.relative(-1);
  281.  
  282. return;
  283. }
  284.  
  285. for (String fieldName : anAssociationsToMap) {
  286.  
  287. currentAssociationName = fieldName;
  288.  
  289. Field associationField = anObject.getClass().getDeclaredField(fieldName);
  290.  
  291. associationField.setAccessible(true);
  292.  
  293. Class<?> associationFieldType = null;
  294.  
  295. Collection<Object> collection = null;
  296.  
  297. if (Collection.class.isAssignableFrom(associationField.getType())) {
  298. collection = mappedCollections.get(fieldName);
  299.  
  300. if (collection == null) {
  301. collection = this.createCollectionFrom(associationField.getType());
  302. mappedCollections.put(fieldName, collection);
  303. associationField.set(anObject, collection);
  304. }
  305.  
  306. ParameterizedType parameterizeType = (ParameterizedType) associationField.getGenericType();
  307. associationFieldType = (Class<?>) parameterizeType.getActualTypeArguments()[0];
  308.  
  309. } else {
  310. associationFieldType = associationField.getType();
  311. }
  312.  
  313. String columnName = this.fieldNameToColumnName(fieldName);
  314.  
  315. ResultSetObjectMapper<Object> mapper =
  316. new ResultSetObjectMapper<Object>(
  317. aResultSet,
  318. associationFieldType,
  319. this.toObjectPrefix(columnName),
  320. this.joinOn());
  321.  
  322. Object associationObject = mapper.mapResultToType();
  323.  
  324. if (collection != null) {
  325. collection.add(associationObject);
  326. } else {
  327. associationField.set(anObject, associationObject);
  328. }
  329. }
  330. }
  331.  
  332. } catch (Exception e) {
  333. throw new IllegalArgumentException(
  334. "Cannot map object association for "
  335. + currentAssociationName
  336. + " because: "
  337. + e.getMessage(),
  338. e);
  339. }
  340. }
  341.  
  342. private ResultSet resultSet() {
  343. return this.resultSet;
  344. }
  345.  
  346. private Class<? extends T> resultType() {
  347. return this.resultType;
  348. }
  349.  
  350. private String toObjectPrefix(String aColumnName) {
  351. String objectPrefix = "o_"+aColumnName+"_";
  352.  
  353. return objectPrefix;
  354. }
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement