web-dev-qa-db-ja.com

Spring FrameworkアプリケーションのJDBCでのRowMapperの使用に関するいくつかの疑問

Spring FrameworkでJDBCを使用してデータベースでクエリを実行する方法を研究しています。

私はこのチュートリアルに従っています: http://www.tutorialspoint.com/spring/spring_jdbc_example.htm

このチュートリアルでは、必要なCRUDメソッドのみを定義するStudentDAOインターフェイスを定義します。

次に、Studentデータベーステーブルで永続化するエンティティであるStudentクラスを定義します。

次に、RowMapperインターフェイスの特定の実装であるStudentMapperクラスが定義されます。この場合、StudentMapperインターフェイスは、/ **の特定のレコードをマップするために使用されますStudentオブジェクトへの/ ResultSet/=/= /(クエリによって返される)。

次に、StudentDAOインターフェースの実装を表すStudentJDBCTemplateがあります。このクラスでは、インターフェースで定義されたCRUDメソッドを実装します。

OK、そして今、StudentMapperクラスがどのように機能するかについて疑問があります:このStudentJDBCTemplateクラスには、 Studentデータベーステーブルにあります。これは次のとおりです。

   public List<Student> listStudents() {
      String SQL = "select * from Student";
      List <Student> students = jdbcTemplateObject.query(SQL, 
                                new StudentMapper());
      return students;
   }

ご覧のように、このメソッドはStudentオブジェクトのリストを返し、次のように動作します。

最初に行うことは、Studentデータベーステーブルのすべてのレコードを返すクエリを定義することですSQL文字列で。

次に、このクエリはjdbcTemplateObjectオブジェクトのクエリメソッド呼び出しによって実行されます(つまり、JdbcTemplateSpring class **の意味です)

このメソッドは2つのパラメーターを取ります。SQL文字列(実行する必要があるSQLクエリを含む)と、ResultSetオブジェクトが返す新しいStudentMapperオブジェクトクエリと、そのレコードを新しいStudentオブジェクトにマッピングします

ここを読む: http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html sayas that:Execute a静的SQLをクエリし、RowMapperを介して各行をJavaオブジェクトにマッピングします。

私の疑いは、StudentMappermapRow()メソッドを使用してStudentオブジェクトにResultSetレコードをマップするという事実に関連しています。これはコードです。

package com.tutorialspoint;

import Java.sql.ResultSet;
import Java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

public class StudentMapper implements RowMapper<Student> {
   public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
      Student student = new Student();
      student.setId(rs.getInt("id"));
      student.setName(rs.getString("name"));
      student.setAge(rs.getInt("age"));
      return student;
   }
}

では、誰がこれをmapRowメソッドと呼ぶのでしょうか? Spring Frameworkによって自動的に呼び出されますか? (この例では手動で呼び出されることはないため...)

Tnx

アンドレア

次に、このクエリはjdbcTemplateObjectオブジェクトのクエリメソッド呼び出しによって実行されます(つまり、JdbcTemplateSpring class **の意味です)

15
AndreaNobili

RowMapperのインスタンスをJdbcTemplateメソッドに渡すとき

_List <Student> students = jdbcTemplateObject.query(SQL, new StudentMapper());
_

JdbcTemplateは、呼び出したメソッドに応じて、JDBC接続から取得した結果セットでマッパーを内部的に使用して、要求されたタイプのオブジェクトを作成します。たとえば、JdbcTemplate#query(String, RowMapper)を呼び出したため、このメソッドはString SQLを使用してデータベースを照会し、ResultSetの各「行」をループします。

_ResultSet rs = ... // execute query
List<Student> students = ...// some list
int rowNum = 0;
while(rs.next()) {
    Student student = rowMapper.mapRow(rs, rowNum);
    students.add(student);
    rowNum++;
}

return students;
_

したがって、SpringJdbcTemplateメソッドは、指定したRowMapperを使用し、そのmapRowメソッドを呼び出して、期待される戻りオブジェクトを作成します。

Martin Fowlerの Data MapperTable Data Gateway と組み合わせて見ると、これらの物がどのように分散され、提供されるのかがわかります 低結合

23

次に、BeanPropertyRowMapperで使用する典型的なパターンを示します。それは多くのコーディングを節約します。クエリは、クラスのプロパティ名と一致するように各列をエイリアスする必要があります。この場合 species_name as speciesと他の列名はすでに一致しています。

public class Animal {
    String species;
    String phylum;
    String family;
    ...getters and setters omitted
}

@Repository
public class AnimalRepository {
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public List<Animal> getAnimalsByPhylum(String phylum) {
        String sql = " SELECT species_name as species, phylum, family FROM animals"
                 +" WHERE phylum = :phylum";

        Map<String, Object> namedParameters = new HashMap<String, Object>();
        namedParameters.put("phylum", phylum);
        SqlParameterSource params = new MapSqlParameterSource(namedParameters);
        List<Animal> records = namedParameterJdbcTemplate.query(sql,
                params, BeanPropertyRowMapper.newInstance(Animal.class));

        return records;
    }
}

別の方法は、行ごとにさらにカスタマイズが必要な場合にRowMapperを使用することです(この例では匿名クラスを使用します)。

    List<Animal> records = namedParameterJdbcTemplate.query(sql,
            params, new RowMapper<Animal>(){
        public Animal mapRow(ResultSet rs, int i) throws SQLException {
            Animal animal = new Animal();   
            animal.setSpecies(rs.getString("species_name"));
            if (some condition) {
                animal.setPhylum(rs.getString("phylum"));
            } else {
                animal.setPhylum(rs.getString("phylum")+someThing());
            }
            animal.setFamily(rs.getString("family"));

            return animal;
        }
    });
4
Jim

SpringでRowMapperを使用する

import Java.sql.ResultSet;
import Java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

public class RowsMap implements RowMapper<EmpPojo>{

    @Override
    public EmpPojo mapRow(ResultSet rs, int counts) throws SQLException {
        EmpPojo em=new EmpPojo();
        em.setEid(rs.getInt(1));
        em.setEname(rs.getString(2));
        em.setEsal(rs.getDouble(3));

        return em;
    }

}

Finally in Main class

List<EmpPojo> lm=jt.query("select * from emps", new RowsMap());
for(EmpPojo e:lm)
{
    System.out.println(e.getEid()+" "+e.getEname()+" "+e.getEsal());
}
2
Raja Rao

それでは、誰がこのmapRowメソッドを呼び出すのでしょうか? Spring Frameworkによって自動的に呼び出されますか? (この例では手動で呼び出されることはないため...)

これは、スプリングフレームワークによって自動的に呼び出されます。必要なのは、指定することだけです

  1. 接続パラメーター、
  2. SQL文
  3. パラメータを宣言し、パラメータ値を提供します
  4. 反復ごとに作業を行います。
1
Arsen Alexanyan