在我的应用程序中,我使用Apache的DBUtils类从MySQL数据库中读取。我编写了一个自定义的BasicRowProcessor,它使用数据对象字段上的注释来读取数据库中的列。它在代码方面非常有效,但是当我拉大量行时,性能相当慢。例如,使用此代码,1500行x 35列结果集将花费800毫秒,但如果我使用标准JDBC代码,则只需80毫秒。
问题 - 我该怎么做才能加快这段代码的速度?具体来说,我使用了大量的反思和注释 - 我是否缺少加快速度的技巧?
@Override
public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException
{
T data = type.newInstance();
Field[] f = type.getFields();
for (int i=0; i<f.length; i++)
{
Field field = f[i];
if (field.isAnnotationPresent(DBColumn.class))
{
String columnName = field.getAnnotation(DBColumn.class).name();
}
if (field.getType().getName().equals("int"))
{
field.setInt(data, rs.getInt(columnName));
}
else if (field.getType().getName().equals("long"))
{
field.setLong(data, rs.getLong(columnName));
}
// .... for all the other types
}
return data;
}
答案 0 :(得分:1)
也许是建立&amp;缓存行映射逻辑,因此您不必扫描字段,注释,结果集元数据和每次都有类型。
JDBC元数据访问速度特别慢。
在此示例中,您可以提供字符串“key”,以便为不同的结果集类型(不同的列结构)启用映射器的高效缓存。
public BasicRowProcessor getReflectiveRowMapper (ResultSet rs, String resultSetKey, Class<T> type) {
String key = resultSetKey+"-"+type;
BasicRowProcessor result = rrmCache.get( key);
if (result != null) {
result = buildReflectiveRowMapper (rs, resultSetKey, type);
rrmCache.put( key, result);
}
return result;
}
public BuiltRowProcessor buildReflectiveRowMapper (ResultSet rs, String resultSetKey, Class<T> type) {
}
然后..
public class BuiltRowProcessor extends BasicRowProcessor {
protected FieldMapping[] mappings;
@Override
public <T> T toBean (ResultSet rs, Class<T> type) throws SQLException {
T data = type.newInstance();
for (FieldMapping field : mappings) {
field.mapField( rs, data);
}
return data;
}
}
abstract public class FieldMapping {
protected Field field;
protected int columnIndex;
// constructor..
abstract public void mapField (ResultSet rs, Object target) throws SQLException;
protected void writeField (Object target, Object value) {
try {
field.setValue(target, value); // or whatever API.
} catch (Exception x) {
throw new RuntimeException("error writing field: "+field, x);
}
}
}
public IntMapping extends FieldMapping {
// constructor..
public void mapField (ResultSet rs, Object target) throws SQLException {
int value = rs.getInt(columnIndex);
writeField( target, value);
}
}
答案 1 :(得分:0)
不要比较类型的名称。将类型与int.class,long.class等进行比较
事实上,你不需要所有这些&#39;如果&#39;声明。只需调用Field.set(),使用ResultSet.getObject()作为参数。所有正确的事情都会在内部发生。但我不会说这会更快。
您最好使用java.beans Introspector的反射工具,因为它会为您缓存所有反射内容。