DBの検索データをListで取得した後に編集しようとするとListの件数分ループさせる必要がある。 Listでまとめて取得した後ではなく、DBからデータ1件を取得するタイミングで独自の処理が挟めれば効率がよい。 SpringJDBCではそれを実現する仕組みとしてBeanPropertyRowMapperを用意している。
BeanPropertyRowMapperを利用すると、独自処理を行単位や列単位で入れることができる。DBのデータを空白トリムしたいときなどに便利。
以下の方法で独自処理を入れることができる。
package test;
import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class SampleDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<SampleBean> select(){
String sql = "select id, name from sampletbl";
List<SampleBean> ret = jdbcTemplate.query(sql,
new BeanPropertyRowMapper<SampleBean>(SampleBean.class){
// 行単位で呼ばれる
public SampleBean mapRow(ResultSet rs, int rowNumber)
throws SQLException{
System.out.println("行番号 [" + rowNumber + "]");
return super.mapRow(rs, rowNumber);
}
// 列単位で呼ばれる
public Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd)
throws SQLException{
System.out.println("列情報 [" + rs.getMetaData().getColumnName(index)
+ "=" + rs.getObject(index) + "]");
return super.getColumnValue(rs, index, pd);
}
}
);
return ret;
}
}
query()などJdbcTemplateの検索メソッド群の中にはRowMapper(インタフェース)を引数にとるものがある。
RowMapperの具象クラスBeanPropertyRowMapper(Spring提供)を使うことにより独自処理の追加が可能となる。
なおBeanPropertyRowMapperはテーブルのデータをBeanにマッピングしてくれるクラスである。コンストラクタの引数にBeanのクラスを指定する。
List ret = jdbcTemplate.query(sql, new BeanPropertyRowMapper(SampleBean.class) {
SampleBeanクラス
package test;
public class SampleBean {
public int id;
public String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
BeanPropertyRowMapperのmapRowメソッドをオーバーライドする。
public SampleBean mapRow(ResultSet rs, int rowNumber) throws SQLException{
~ 独自処理を挿入 ~
return super.mapRow(rs, rowNumber);
}
BeanPropertyRowMapperのgetColumnValueメソッドをオーバーライドする。
public Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd)
throws SQLException{
~ 独自処理を挿入 ~
return super.getColumnValue(rs, index, pd);
}
getColumnValue()の引数PropertyDescriptorはBeanクラスの情報を持つクラス。Beanクラスの属性名や属性型などが取得できる。
■サンプル
以下は実際に独自処理を入れたサンプル。mapRowで名前の末尾に"様"を付加し、getColumnValueではCHAR型の場合にトリムを行っている。順番的にはレコード毎にgetColumnValue → mapRowの順に呼ばれる。
List ret = jdbcTemplate.query("select id, name from sampletbl",
new BeanPropertyRowMapper<SampleBean>(SampleBean.class){
// 行単位で呼ばれる
public SampleBean mapRow(ResultSet rs, int rowNumber)
throws SQLException {
// 名前の末尾に"様"を付加
SampleBean bean = super.mapRow(rs, rowNumber);
bean.setName(bean.getName() + "様");
return bean;
}
// 列単位で呼ばれる
public Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd)
throws SQLException {
// CHAR型の場合はトリム
if(rs.getMetaData().getColumnType(index) == java.sql.Types.CHAR){
return ((String)super.getColumnValue(rs, index, pd)).trim();
}
return super.getColumnValue(rs, index, pd);
}
}
);