我有这个通用函数来填充数据库中的对象的ArrayList。问题是我从DB获取一个通用的ArrayList类,然后创建我需要创建的ArrayList的特定子类,然后从通用ArrayList复制到我的子类。我想消除从一个数组复制到另一个数组的不必要的步骤,因为数百行的性能不会很好。如何使用泛型消除该步骤?
因此,要使用更具体的示例,我有一个像
这样的数据类public class UserData {}
然后是类
public class UserSet extends ArrayList<UserData>
我将使用类似
的函数调用填充UserSet对象UserSet s = selectAll("SELECT * FROM users", UserSet.class);
和我查询数据库并返回UserSet实例的常规函数是这样的。
public static <T, S extends List<T>> S selectAll(String sql, Class<S> listType, Object...args) throws Exception
{
// t = UserData.class in my example
Class<T> t = (Class<T>)((ParameterizedType)listType.getGenericSuperclass()).getActualTypeArguments()[0];
// From Apache's DBUtils project
QueryRunner run = new QueryRunner();
// AnnotatedDataRowProcessor is my class that just converts a DB row into a data object
ResultSetHandler<List<T>> h = new BeanListHandler<T>(t, new AnnotatedDataRowProcessor());
Connection conn = DB.getConnection();
try
{
// creates the new instance of my specific subclass of ArrayList
S result = listType.newInstance();
// returns the ArrayList which I then copy into result
result.addAll(run.query(conn, sql, h, args));
return result;
}
finally
{
DbUtils.close(conn);
}
}
答案 0 :(得分:1)
您可以自定义BeanListHandler
,如下所示:
ResultSetHandler<List<T>> h = new BeanListHandler<T>(t, new AnnotatedDataRowProcessor()) {
@Override
public List<T> handle(ResultSet rs) throws SQLException {
List<T> rows = listType.newInstance();
while (rs.next()) {
rows.add(this.handleRow(rs));
}
return rows;
}
};
你可能需要一些演员来进行编译,但这是一般的想法。
然后调用run.query(conn, sql, h, args)
将直接创建您正在寻找的类型。
答案 1 :(得分:0)
我实际上必须将Class类型传递给AnnotatedDataRowProcessor的构造函数,所以我不会破坏这个BeanListHandler中的接口方法。
private Class<?> type;
public <T> AnnotatedDataRowProcessor(Class<T> type)
{
this.type = type;
}
@Override
public <T> List<T> toBeanList(ResultSet rs, Class<T> type) throws SQLException
{
try
{
List<T> list = (List<T>)this.type.newInstance();
while (rs.next())
{
list.add(toBean(rs,type));
}
return list;
}
catch (IllegalAccessException ex)
{
throw new SQLException(ex.getMessage());
}
catch (InstantiationException ex)
{
throw new SQLException(ex.getMessage());
}
}