15

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

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

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

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

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

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

さて、 StudentMapperクラスがどのように機能するかについて疑問があります。このStudentJDBCTemplateクラスには、Studentデータベーステーブルにあるすべてのレコードのリストを返すメソッドが定義されています。これは次のとおりです。

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

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

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

次に、このクエリは、jdbcTemplateObjectオブジェクト(つまり、JdbcTemplateSpringクラス**のインスタンス)に対するqueryメソッド呼び出しによって実行されます

このメソッドは2つのパラメーターを取ります。SQL文字列(実行する必要のあるSQLクエリを含む)と、クエリによって返されたResultSetオブジェクトを受け取り、そのレコードを新しいStudentオブジェクトにマップする新しいStudentMapperオブジェクトです。

ここを読む:http : //static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html次のように言います:静的SQLを指定してクエリを実行し、各行をJavaにマッピングしますRowMapperを介したオブジェクト。

私の疑問は、StudentMapperがmapRow()メソッドを使用して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クラス**のインスタンス)に対するqueryメソッド呼び出しによって実行されます

4

4 に答える 4

23

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

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

呼び出したJdbcTemplateメソッドに応じて、JDBC接続から取得した結果セットでマッパーを内部的に使用して、要求されたタイプのオブジェクトを作成します。たとえば、を呼び出したので、メソッドは文字列SQLを使用してデータベースにクエリを実行し、次のような種類のJdbcTemplate#query(String, RowMapper)各「行」をループします。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、期待される戻りオブジェクトを作成します。

これらがどのように分散され、低結合を提供するかについては、 MartinFowlerデータマッパーをTableDataGatewayと組み合わせて確認することをお勧めします。

于 2013-02-27T17:57:53.333 に答える
4

これが私が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;
        }
    });
于 2013-02-27T18:02:29.657 に答える
2

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());
}
于 2013-10-30T11:16:31.620 に答える
1

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

これは、SpringFrameworkによって自動的に呼び出されます。必要なのは指定することだけです

  1. 接続パラメータ、
  2. SQLステートメント
  3. パラメーターを宣言し、パラメーター値を提供します
  4. 反復ごとに作業を行います。
于 2013-02-27T17:56:05.907 に答える