カラムマッピングの高速化

S2Daoを使ってエンティティのリストを取得するとき、

  1. エンティティのプロパティ数が多く
  2. かつ、一度に取得されるエンティティ数が多い

ような場合、大量のsetterがリフレクションで呼ばれることによってパフォーマンスが悪化するようです。そこで、次のような対策を立ててみました。

public interface DirectMapping {
    public void read(ResultSet rs) throws SQLException;
}
public class SomeEntity implements DirectMapping {
    private String aaa;
    private String bbb;
    ...
    public void read(ResultSet rs) throws SQLException {
        aaa = rs.getString("aaa");
        bbb = rs.getString("bbb");
        ...
    }
}

このようにマッピングインターフェイスを用意し、ResultSetを直接読みに行くメソッドをエンティティに実装します。

次に、org.seasar.dao.impl.AbstractBeanMetaDataResultSetHandler#createRow()の処理内容を横取りします。

protected Object createRow(ResultSet rs, Set columnNames) throws SQLException {
    Object row = ClassUtil.newInstance(beanMetaData_.getBeanClass());
    if(row instanceof DirectMapping) {
        DirectMapping mapping = (DirectMapping)row;
        mapping.read(rs);
        return mapping;
    }
    ...
}

以下は実際のあるケースにおける計測結果です。


エンティティのプロパティ数: 22
エンティティの取得数: 5000程度
S2Daoによる取得平均所要時間: 759ms
DirectMappingによる取得平均所要時間: 297ms


せっかくのO/Rマッピングの意義が台無しですが、馬鹿にできない程の効果が得られるので、パフォーマンスが気になる場面ではこの方法を多用しています。