在我的应用程序中,我使用Apache的DBUtils类从MySQL数据库读取数据。我编写了一个自定义BasicRowProcessor,它使用数据对象字段上的注释从数据库中读取列。它在代码方面工作得很好,但是当我拉很多行时,性能相当慢。例如,使用此代码,1500行x 35列的结果集将花费800ms,但如果使用标准JDBC代码,则只需花费80ms。
问题-我能做些什么来加速这段代码?具体来说,我使用了大量的反射和注释——我是否遗漏了一些技巧来加快速度?
@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;
}
可能是build &缓存行映射逻辑,这样你就不必扫描字段、注释、结果集元数据&
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);
}
}
不要比较类型的名称。比较类型,与int.class、long.class等
事实上,你不需要所有这些'if'语句。只需调用Field.set(),使用ResultSet.getObject()作为参数。所有正确的事情都会在内部发生。但我不是说这会更快。
你最好使用java的反射功能。