使用jdbc时泛型类型的Java反射 - java

在C#中,我有一个实用程序,可将Datatable转换为指定模型的列表,如下所示:

Datatable dt = conn.GetDataTable(); 
List<BookModel> result = EntityHelper<BookModel>.GetListModel(dataTable); 

使用泛型的GetListModel()方法如下所示:

public static List<T> GetListModel(DataTable dt)
    {
        List<T> lObject= new List<T>();
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            T obj = new T();
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                int index = IndexOfField( dt.Columns[j].ColumnName );
                if (index != -1)
                {
                    PropertyInfo pi = obj.GetType().GetProperties()[index];
                    Type propType = pi.PropertyType;
                    if (propType.IsGenericType && (propType.GetGenericTypeDefinition() == typeof( Nullable<> )))
                    {
                        propType = propType.GetGenericArguments()[0];
                    }
                    if (propType.IsEnum)
                    {
                        int objectValue = 0;
                        Int32.TryParse( dt.Rows[i][j].ToString(), out objectValue );
                        pi.SetValue( obj, Enum.ToObject( propType, objectValue ), null );
                    }
                    else if (dt.Columns[j].DataType == propType && dt.Rows[i][j] != DBNull.Value)
                    {
                        pi.SetValue( obj, dt.Rows[i][j], null );
                    }
                    else if ((propType.Name.Equals( "Boolean" ) || propType.Name.Equals( "bool" )) && dt.Rows[i][j] != DBNull.Value)
                    {
                        pi.SetValue( obj, Convert.ToBoolean( dt.Rows[i][j] ), null );
                    }
                }
            }

            lObject.Add( obj );
        }
        return lObject;
    }

这就是C#的故事,现在回到Java。我正在使用JDBC执行存储的proc并返回ResultSet。但是我发现在Java中,泛型类型在运行时删除了它的信息,所以我不能做这样的事情:

public static <T> List<T> castObject(ResultSet rs)
{
    T x = new T(); //IMPOSSIBLE ;___;
    Field[] fields = x.getClass().getDeclaredFields();
     for(Field field: fields) 
     { 
         field.setAccessible(true); 
     }
    ....
}

如果不可能创建这样的实用程序,那么是否有办法在重新获得结果后减少样板代码?我的表有30列,我不想处理这样的代码:

actor.setFirstName(rs.getString("first_name"));
actor.setLastName(rs.getString("last_name"));
...

参考方案

您可以通过将Class实例作为参数传递给您的方法来实例化该类。具体操作方式取决于您使用的Java版本,但这是Java 9及更高版本的示例(尽管早期版本相似):

public static <T> List<T> castObject(ResultSet rs, Class<T> clazz) throws NoSuchMethodException,
        IllegalAccessException, InvocationTargetException, InstantiationException {

    Constructor<T> constructor = clazz.getConstructor();
    T t = constructor.newInstance();
    ...
}

调用方法:

List<BookModel> bookModels = castObject(rs, BookModel.class);

但是,调用setAccessible可能会出现问题。此讨论显示了一种解决方法。 How to solve InaccessibleObjectException ("Unable to make {member} accessible: module {A} does not 'opens {package}' to {B}") on Java 9?

Java中的“ <<”运算符 - java

最喜欢的语句来自Java的Character类:(1 << Character.PARAGRAPH_SEPARATOR)) >> type PARAGRAPH_SEPARATOR是字节,type是整数。这句话中的操作员,他们做什么?如何以及在哪里可以使用这些运算符?这是oracles java.lang.Character文档。该类中…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

JAVA:如何检查对象数组中的所有对象是否都是子类的对象? - java

我有一个对象数组。现在,我要检查所有这些对象是否都是MyObject的实例。有没有比这更好的选择:boolean check = true; for (Object o : justAList){ if (!(o instanceof MyObject)){ check = false; break; } } java大神给出的解决方案 如果您不喜欢循环,则…