DBからデータを取得するには?(NamedParameterJdbcTemplateのサンプル) | Java Springの逆引きメモ

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

ここでは、SpringJDBCを使用して、DBから値を取得するサンプルを記述します。

NamedParameterJdbcTemplateクラスは、以下のような場合に良く使用します。


 ・SQL文にプレースがあり、プレースホルダに":名前"を使用したい場合


プレースホルダーは普通、"?"です。

プレースホルダに?を使用すると便利ですが、何番目かがよく分からなくなります。

こんなときに上記のように英数字で名前を使えると大変便利ですよね?


NamedParameterJdbcTemplateは、プレースするものがない場合には向きません。

その場合には、SimpleJdbcTemplate の方を使用しましょう!

さて、早速サンプルをみてみましょう。




【DaoインターフェースのJavaコード例】

import java.util.List;
import business.domain.Member;
public interface MemberDao { /** * 会員検索をする。 * @return 検索結果 */ List<Member> findMember();

}

【DaoのJavaコード例】

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.validator.GenericValidator;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;

import business.domain.Member;


public class MemberDaoImpl extends JdbcDaoSupport implements MemberDao {

  //会員情報マッピング
  protected class MemberRowMapper 
  implements ParameterizedRowMapper<Member> {
    
    public Member mapRow(ResultSet rs, int rowNum)
    throws SQLException {
        Member mem = new Member();
        mem.setId(rs.getString("id"));
        mem.setKana(rs.getString("kana"));
        mem.setKanji(rs.getString("kanji"));
      return mem;
    }
  }

  //JDBCのテンプレート
  protected NamedParameterJdbcTemplate namedParameterTemplate;
  protected SimpleJdbcTemplate simpleTemplate;
  //初期化処理
  protected void initDao()
  {
    this.namedParameterTemplate = 
                   new NamedParameterJdbcTemplate(getDataSource());
    this.simpleTemplate = new SimpleJdbcTemplate(getDataSource());
  }
  
  //  
  @SuppressWarnings("unchecked")
  public List<Member> findMember() {
    //
    String sql = "select * from t_member where id=:id";
    //パラメタの設定
    Map key = new HashMap();
    key.put("id", "i0001");

    //会員リスト
    List<Member> memberList = this.namedParameterTemplate.query(
      sql, key, new MemberRowMapper()
    ); 
    
    return memberList;
  }

}



【Springの設定】

  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url">
      <value>jdbc:postgresql://localhost/test?useUnicode=true&amp;characterEncoding=utf-8</value>
    </property>
    <property name="username" value="user" />
    <property name="password" value="pass" />
</bean>
  <bean id="memberDao" class="dao.MemberDaoImpl">
    <property name="dataSource" ref="dataSource" />
  </bean>


【説明】

Javaのクラスは、JdbcDaoSupport を継承してメソッドを実装していきます。

まず準備として、MemberRowMapperのようなマッピングクラスを作成します。

これは、ParameterizedRowMapperを継承して作成します。

実装するのはmapRowメソッドだけで、この中でResultSetとオブジェクトのマッピングをします。


次にするのは、実際のSQLの処理です。

SimpleJdbcTemplate と違うのはプレースするパラメタを設定する部分です。

Mapを用意してそれに値を入れます。

そして、SQL文を作ってnamedParameterTemplate.query( )を呼びます。


Springの設定ファイルでは、データソースと先ほど作成したDaoのクラスを設定するだけです。


これでDBから値を取得できます。



【その他】

SimpleJdbcTemplate と同様に、queryForIntなどの便利なメソッドもあります。


他にも便利なメソッドがあるので使っていきましょう!



【補足】

さて、NamedParameterJdbcTemplateクラスはどうでしたか?

Mapを設定するのが面倒だと思いました?


いえ、ちょっと工夫すればそうでもないんです

ここでは紙面の関係でDaoの中でMapをnewしましたが、本当はDaoを使うクラスがMapを作成すべきです

そして、Mapを引数でDaoに渡します。

そうすると柔軟性の高いDaoになります。


普通、例えば以下のように引数にSQLの検索キーを渡しがちです。


 例:AND検索で、ID、会員名、会員名カナのうち、設定されている値をキーに検索をする場合。


 List<Member> find(String id, String name, String kana);


これでも実装はできるかと思います。

しかし、上記の方法は重大な欠点があるのが分かるでしょうか

将来追加開発で、住所も検索キーにしたい場合はどうでしょう?

このメソッドを使用している箇所すべてを置換して、引数を4つにしないといけません。


これはかなり拡張性を落とします。


それよりも、以下のようにする方が断然、拡張性が高くなります。

 

 List<Member> find(Map key);


さらに、やり方を良くするための工夫は次回 に記述します。





参考:

DIの設定ファイルを書くには?

SpringJDBCの機能について

DBからデータを取得するには?(SimpleJdbcTemplate のサンプル)
NamedParameterJdbcTemplateをうまく使うには?