簡體   English   中英

使用 jdbc 時泛型類型的 java 反射

[英]java reflection for generic type when using jdbc

在 C# 中,我有一個實用程序將 Datatable 轉換為指定 model 的列表,如下所示:

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 來執行存儲過程並返回一個 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 實例作為參數傳遞給您的方法來實例化 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 的調用可能會出現問題。 此討論顯示了一種解決方法。 如何解決 Java 9 上的 InaccessibleObjectException(“無法使 {member} 可訪問:模塊 {A} 不‘打開 {package}’到 {B}”)?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM