カラムマッピングの高速化
S2Daoを使ってエンティティのリストを取得するとき、
- エンティティのプロパティ数が多く
- かつ、一度に取得されるエンティティ数が多い
ような場合、大量の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マッピングの意義が台無しですが、馬鹿にできない程の効果が得られるので、パフォーマンスが気になる場面ではこの方法を多用しています。