Java泛型、反射API和;JDBC:无法将java.lang.Long和java.sql.Timestamp映射到类型

Java泛型、反射API和;JDBC:无法将java.lang.Long和java.sql.Timestamp映射到类型,java,generics,jdbc,Java,Generics,Jdbc,需要使用泛型和java.lang.reflect.*将ResultSet的输出映射到LogEntity的实例的方法。它们的构造函数存在一些长时间戳字段类型的问题 JDK 1.8,Spring Boot 2.2.2,不,我不需要你的Hibernate或JDBCTemplate LogEntity: package com.tb.register.core.entity; import com.tb.register.core.annotation.ColumnName; import lombo

需要使用泛型和java.lang.reflect.*将
ResultSet
的输出映射到
LogEntity
的实例的方法。它们的构造函数存在一些长时间戳字段类型的问题

JDK 1.8,Spring Boot 2.2.2,不,我不需要你的Hibernate或JDBCTemplate

LogEntity

package com.tb.register.core.entity;

import com.tb.register.core.annotation.ColumnName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.sql.Timestamp;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class LogEntity {
  @ColumnName(name = "Rn")
  private Long rn;

  @ColumnName(name = "Id")
  private Long id;

  @ColumnName(name = "Name")
  private String name;

  @ColumnName(name = "Who_Made")
  private Long whoMade;

  @ColumnName(name = "When_Made")
  private Timestamp whenMade;

  @ColumnName(name = "Who_Made_Username")
  private String whoMadeUsername;
}
ColumnName
注释:

package com.tb.register.core.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnName {
  String name();
}
现行方法:

public List<V> getData(
      Connection connection, GridEntity gridEntity, Class<? extends V> classObject) {
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    List<V> rows = new ArrayList<>();
    try {
      preparedStatement = connection.prepareStatement(gridEntity.getMainSQL());
      GridEntity.bindObjectLimit(preparedStatement, gridEntity);
      resultSet = preparedStatement.executeQuery();
      resultSet.setFetchSize(300);
      Field[] fields = classObject.getDeclaredFields();
      for (Field field : fields) {
        field.setAccessible(true);
        log.info("{}, {}", field.getName(), field.getType());
      }
      while (resultSet.next()) {
        V row = classObject.getConstructor().newInstance();
        for (Field field : fields) {
          ColumnName columnName = field.getAnnotation(ColumnName.class);
          if (columnName != null) {
            try {
              if (field.getType() == java.lang.Long.class) {
                field.set(
                    row,
                    field
                        .getType()
                        .getConstructor(java.lang.Long.class)
                        .newInstance(resultSet.getLong(columnName.name())));
              } else if (field.getType() == java.sql.Timestamp.class) {
                field.set(
                    row,
                    field
                        .getType()
                        .getConstructor(java.sql.Timestamp.class)
                        .newInstance(resultSet.getTimestamp(columnName.name())));
              } else {
                field.set(
                    row,
                    field
                        .getType()
                        .getConstructor(String.class)
                        .newInstance(resultSet.getString(columnName.name())));
              }
            } catch (Exception e) {
              log.error("", e);
            }
          }
        }
        rows.add(row);
        //        list.add(
        //            new V(
        //                resultSet.getLong("Rn"),
        //                resultSet.getLong("Id"),
        //                resultSet.getString("Name"),
        //                resultSet.getLong("Who_Made"),
        //                resultSet.getDate("When_Made"),
        //                resultSet.getString("Who_Made_Username")));
      }
      return rows;
    } catch (Exception e) {
      log.error("", e);
    } finally {
      PoolManager.release(resultSet);
      PoolManager.release(preparedStatement);
    }
    return null;
  }
公共列表获取数据(
连接,GridEntity,GridEntity,类
这是在尝试获取
Long
类中的构造函数,该类将
Long
作为参数

没有这样的构造函数

也许您的意思是
getConstructor(long.class)
,选择哪个

选择存在的构造函数。或者跳过反射:

field.set(
    row,
    resultSet.getLong(columnName.name()));

(您也可以对其他分支执行类似操作。事实上,这两个分支都不需要调用复制构造函数,因为您已经可以从结果集中获得正确类型的实例).

我喜欢跳过反射位。它起作用了,谢谢。顺便说一句:如果你看一下堆栈跟踪,这个问题很容易看出来:它的字面意思是,在尝试获取构造函数时出现了问题,它告诉你尝试获取构造函数的行号;以及获取带有某些内容的构造函数是一个问题关于
Long
。您可以将此问题中显示的代码量减少到我在答案顶部显示的代码片段的大致数量;然后可以问“为什么失败/如何修复它”,但人们解决问题所需的时间要少得多。我将在进一步的问题中考虑到这一点
java.lang.NoSuchMethodException: java.sql.Timestamp.<init>(java.sql.Timestamp)
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at com.tb.register.core.repository.GenericRepository.getData(GenericRepository.java:70)
    at com.tb.register.core.repository.LogRepositoryImpl.getLogs(LogRepositoryImpl.java:74)
if (field.getType() == java.lang.Long.class) {
  // ...
  field.getType().getConstructor(java.lang.Long.class)
  // ...
}
field.set(
    row,
    resultSet.getLong(columnName.name()));