DOResultTransformer.java 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package com.primeton.filetransfer.server.template;
  2. import lombok.Getter;
  3. import lombok.NonNull;
  4. import lombok.Setter;
  5. import org.apache.commons.beanutils.BeanUtils;
  6. import org.apache.commons.lang.StringUtils;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import javax.persistence.Column;
  10. import java.lang.reflect.Field;
  11. import java.lang.reflect.Modifier;
  12. import java.sql.SQLException;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import java.util.regex.Matcher;
  16. import java.util.regex.Pattern;
  17. /**
  18. *
  19. * JDBC ResultSet 转 Entity Object 快捷方法
  20. *
  21. * <pre>
  22. *
  23. * Created by zhaopx.
  24. * User: zhaopx
  25. * Date: 2022/3/1
  26. * Time: 下午6:35
  27. * Vendor: primeton.com
  28. *
  29. * </pre>
  30. *
  31. * @author zhaopx
  32. */
  33. public class DOResultTransformer<T> implements ResultTransformer<T> {
  34. /**
  35. *
  36. */
  37. private static final long serialVersionUID = 1L;
  38. private static Logger logger = LoggerFactory.getLogger(DOResultTransformer.class);
  39. /**
  40. * 驼峰转下划线
  41. */
  42. private static Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
  43. @Getter
  44. @Setter
  45. class FieldInfo {
  46. final String fieldName;
  47. final Class<?> fieldType;
  48. public FieldInfo(String fieldName, Class<?> fieldType) {
  49. this.fieldName = fieldName;
  50. this.fieldType = fieldType;
  51. }
  52. }
  53. private final Class resultClass;
  54. private boolean isInitialized;
  55. private final Map<String, FieldInfo> aliasFieldMap = new HashMap<>();
  56. public DOResultTransformer(@NonNull Class<T> resultClass) {
  57. this.resultClass = resultClass;
  58. isInitialized = false;
  59. }
  60. public T transformTuple(Object tuple[], String aliases[]) throws SQLException {
  61. Object result = null;
  62. if (!isInitialized) {
  63. initialize(aliases);
  64. }
  65. // 从构造方法进入
  66. try {
  67. result = resultClass.newInstance();
  68. for (int i = 0; i < tuple.length; i++) {
  69. final FieldInfo fieldInfo = aliasFieldMap.get(StringUtils.upperCase(aliases[i]));
  70. if(fieldInfo == null) {
  71. continue;
  72. }
  73. BeanUtils.setProperty(result, fieldInfo.getFieldName(), tuple[i]);
  74. }
  75. } catch (Exception e) {
  76. String reason = new StringBuilder().append("Could not instantiate resultclass: ").append(resultClass.getName()).toString();
  77. throw new SQLException(reason);
  78. }
  79. return (T)result;
  80. }
  81. private void initialize(String aliases[]) {
  82. final Field[] declaredFields = resultClass.getDeclaredFields();
  83. for (Field declaredField : declaredFields) {
  84. // final 和 static 修饰的都不是 bean 字段
  85. if(Modifier.isFinal(declaredField.getModifiers()) || Modifier.isStatic(declaredField.getModifiers())) {
  86. continue;
  87. }
  88. // 字段名称和类型
  89. final String fieldName = declaredField.getName();
  90. final Class<?> fieldType = declaredField.getType();
  91. // 获取字段上的注解
  92. final Column columnAnno = declaredField.getAnnotation(Column.class);
  93. if(columnAnno == null || StringUtils.isBlank(columnAnno.name())) {
  94. // 无注解
  95. aliasFieldMap.put(StringUtils.upperCase(humpToLine(fieldName)), new FieldInfo(fieldName, fieldType));
  96. } else {
  97. // 有注解, 并且 Column name 不为 null
  98. aliasFieldMap.put(StringUtils.upperCase(columnAnno.name()), new FieldInfo(fieldName, fieldType));
  99. }
  100. }
  101. isInitialized = true;
  102. }
  103. /**
  104. * 驼峰转下划线
  105. */
  106. public static String humpToLine(String str) {
  107. Matcher matcher = HUMP_PATTERN.matcher(str);
  108. StringBuffer sb = new StringBuffer();
  109. while (matcher.find()) {
  110. matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
  111. }
  112. matcher.appendTail(sb);
  113. return sb.toString();
  114. }
  115. public boolean equals(Object o) {
  116. if (this == o)
  117. return true;
  118. if (o == null || getClass() != o.getClass())
  119. return false;
  120. DOResultTransformer that = (DOResultTransformer) o;
  121. if (!resultClass.equals(that.resultClass))
  122. return false;
  123. return true;
  124. }
  125. public int hashCode() {
  126. int result = resultClass.hashCode();
  127. result = 31 * result;
  128. return result;
  129. }
  130. }