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

问题描述 投票:0回答:1

需要一种使用泛型和java.lang.reflect。*将ResultSet的输出映射到LogEntity的实例的方法。它们是Long&Timestamp字段类型的一些构造函数问题。

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;
  }

我们得到的是:

2020-01-18 21:33:47,754 INFO  [http-nio-9111-exec-2] com.tb.register.core.entity.GridEntity: 
where: [], 
mainSQL: select * from( select /*+ first_rows(10) */ t.*, row_number() over(order By t.id asc) Rn from fr_cc_logs_v t ) where rn between :lowerLimit And :upperLimit order by rn asc
countSQL: select count(*) from fr_cc_logs_v t
2020-01-18 21:33:47,765 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: rn, class java.lang.Long
2020-01-18 21:33:47,767 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: id, class java.lang.Long
2020-01-18 21:33:47,767 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: name, class java.lang.String
2020-01-18 21:33:47,767 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: whoMade, class java.lang.Long
2020-01-18 21:33:47,767 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: whenMade, class java.sql.Timestamp
2020-01-18 21:33:47,769 INFO  [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: whoMadeUsername, class java.lang.String
2020-01-18 21:33:47,774 ERROR [http-nio-9111-exec-2] com.tb.register.core.repository.GenericRepository: 
java.lang.NoSuchMethodException: java.lang.Long.<init>(java.lang.Long)
    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:63)
    at com.tb.register.core.repository.LogRepositoryImpl.getLogs(LogRepositoryImpl.java:74)
    at com.tb.register.core.repository.LogRepositoryImpl$$FastClassBySpringCGLIB$$b1dfd861.invoke(<generated>)

...

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)
java generics jdbc
1个回答
1
投票
if (field.getType() == java.lang.Long.class) {
  // ...
  field.getType().getConstructor(java.lang.Long.class)
  // ...
}

这是在Long类中获取一个以Long作为参数的构造函数。

没有这样的构造函数。

也许您是指getConstructor(long.class),它将选择this constructor

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

field.set(
    row,
    resultSet.getLong(columnName.name()));
© www.soinside.com 2019 - 2024. All rights reserved.