Generic RowMapper JDBC



我正在尝试为JDBC创建一个通用的行映射器。

我最初的尝试看起来像:

public class GenericRowMapper<T> implements RowMapper<T> {
private final Class<?> clazz;
public GenericRowMapper(T instance) {
this.clazz = instance.getClass().getComponentType();
}
@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields){
System.out.println("field name : " + f.getName() + " , type : " + f.getType());
}
try {
return (T) clazz.getConstructor().newInstance();
} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}

但是在构造函数中,getComponentType()返回null,因此clazz = null;和我无法取得任何进展。

我做错了什么?

我做错了什么?

许多新手程序员都会犯的错误(一些专家也会犯!)。

读取文档失败.

如果这样做了,您可能已经注意到getComponentType()的文档告诉您它返回数组的组件类型

给定Class<?> c = String[].class,我可以调用c.getComponentType()并返回String.class。或者new String[10].getClass().getComponentType()也会得到相同的结果

你显然是在一个不代表数组类型的类上调用.getComponentType(),因此,你得到了null

做对了

你的代码很混乱。T是一个类型变量,因此,接受T instance的参数意味着你必须提供它的实际实例,即,如果你有一个RowMapper,将一行映射到字符串,你必须提供一个字符串,这是没有意义的。假设你真正想要的arg是Class<T>,在这种情况下,瞧,这就是你的类。一开始就不需要对它调用.getClass().getComponentType()。如果你真的打算让这个方法要求你首先传递一个实际的实例,.getClass()将是你可能想要的方法,除了我不认为这会起作用:.getClass()总是给你实际的类型,即在类型列表的变量上调用.getClass()永远不能返回List.class-它可能会返回ArrayList.class或一些实现列表的匿名内部类。

其余的代码同样令人困惑

.getDeclaredFields()只返回类定义本身的字段,而不是任何父类(父类的字段与其他类的任何实例一样多)—再次,请阅读文档以了解这一点。

'print a stack trace, return null'是非常愚蠢的异常处理。正确的"我不(还)关心它"异常处理程序是throw new RuntimeException("unhandled", e);-更短,更好。没有理由不这样做。修改IDE的模板

不支持现代java

许多,许多现代的java(特别是包括record功能)有一个不可变的类,因此你不能只是"设置"一堆字段,也不会有一个无参数的构造函数(.getConstructor()让你,因此,.getConstructor()会失败)。相反,构造函数本身接受所有参数;因此,您对字段不感兴趣,而对构造函数的参数感兴趣。只是可以有多个参数,而且类不(必须)包含参数名。

相关内容

  • 没有找到相关文章

最新更新