简体   繁体   English

关于RowMapper在Spring Framework应用程序中使用JDBC的一些疑问

[英]Some doubts about RowMapper use in JDBC in a Spring Framework application

I am studying how to execute query on a database using JDBC in Spring Framework. 我正在研究如何在Spring Framework中使用JDBC对数据库执行查询。

I am following this tutorial: http://www.tutorialspoint.com/spring/spring_jdbc_example.htm 我正在学习本教程: http//www.tutorialspoint.com/spring/spring_jdbc_example.htm

In this tutorial I define a StudentDAO interface which only define the CRUD method that I want. 在本教程中,我定义了一个StudentDAO接口,它只定义了我想要的CRUD方法。

Then is defined the Student class that is the entity that I want to persist on the Student database table. 然后定义Student类,它是我想要在Student数据库表上保留的实体。

Then is defined the StudentMapper class that is a specific implementation of RowMapper interface that, in this case, is used to map a specific record in the ResultSet (returned by a query) to a Student object. 然后定义StudentMapper类,它是RowMapper接口的特定实现,在这种情况下,用于将ResultSet中的特定记录(由查询返回)映射到Student对象。

Then I have the StudentJDBCTemplate that rappresent the implementation of my StudentDAO interface, in this class I implement the CRUD method that was defined in the interface. 然后,我有我的rappresent接口StudentDAO的实施StudentJDBCTemplate,在这个类我实现的接口中定义的CRUD方法。

Ok, and now I have a doubt about how the StudentMapper class work: in this StudentJDBCTemplate class there is defined the method that return the list of all record that are in the Student database table, this one: 好了,现在我有一个关于如何StudentMapper类工作的疑问:在这个StudentJDBCTemplate类有定义的返回是在学生数据库表中的所有记录的列表的方法,这其中:

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

How you can see, this method return a List of Student object and work in the following way: 你怎么看,这个方法返回一个List of Student对象并按以下方式工作:

the first thing that it do is to define the query that return all record in the Student database table in the SQL String. 它首先要做的是定义返回 SQL String中Student数据库表所有记录的查询。

Then this query is executed by the query method call on the jdbcTemplateObject object (that is an istance of JdbcTemplate Spring class** 然后通过jdbcTemplateObject对象上的查询方法调用执行此查询(这是JdbcTemplate Spring类的一个等级**

This method take two parameter: the SQL String (that contains the SQL query that must be executed) and a new StudentMapper object that take the ResultSet object returned by the query and map it's record on a new Student object 此方法有两个参数:SQL String(包含必须执行的SQL查询)和一个新的StudentMapper对象,它接受查询返回的ResultSet对象并将其记录映射到新的Student对象上

Reading here: http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html sayas that: Execute a query given static SQL, mapping each row to a Java object via a RowMapper. 在这里阅读: http ://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html sayas: 执行给定静态SQL的查询,将每一行映射到Java通过RowMapper对象。

My doubt is related to the fact that my StudentMapper map a ResultSet record on a Student object using the mapRow() method, this is the code: 我的疑问是有关事实,我的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;
   }
}

So, who call this mapRow method? 那么,谁调用这个mapRow方法呢? is it called automatically by the Spring Framework? 它是由Spring Framework自动调用的吗? (because in this example is never called manually...) (因为在这个例子中永远不会手动调用...)

Tnx TNX

Andrea 安德里亚

Then this query is executed by the query method call on the jdbcTemplateObject object (that is an istance of JdbcTemplate Spring class** 然后通过jdbcTemplateObject对象上的查询方法调用执行此查询(这是JdbcTemplate Spring类的一个等级**

When you pass an instance of your RowMapper to the JdbcTemplate method RowMapper的实例传递给JdbcTemplate方法时

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

The JdbcTemplate depending on which method you called, will internally use the mapper with the result set it gets from the JDBC Connection to create an object of your requested type. JdbcTemplate取决于您调用的方法,将在内部使用映射器以及从JDBC Connection获取的结果集,以创建所请求类型的对象。 For example, since you called JdbcTemplate#query(String, RowMapper) , the method will use your String SQL to query the database and will loop through each "row" in the ResultSet kind of like this: 例如,由于您调用了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;

So, Spring 's JdbcTemplate method will use the RowMapper you provide and call its mapRow method to create the expected return object. 因此, SpringJdbcTemplate方法将使用您提供的RowMapper并调用其mapRow方法来创建预期的返回对象。

You might like to look at Martin Fowler's Data Mapper in conjunction with Table Data Gateway for an idea of how these things are distributed and provide low coupling . 您可能希望将Martin Fowler的数据映射器表数据网关结合使用,以了解这些内容如何分布并提供低耦合

Here is the typical pattern I use with BeanPropertyRowMapper. 这是我与BeanPropertyRowMapper一起使用的典型模式。 It saves a lot of coding. 它节省了大量的编码。 Your query needs to alias each column to match the property name in the class. 您的查询需要对每列进行别名以匹配类中的属性名称。 In this case species_name as species and the other column names happen to match already. 在这种情况下, 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;
    }
}

An alternative is to use a RowMapper (this example just uses an anonymous class) when you need more customization per row: 另一种方法是在每行需要更多自定义时使用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;
        }
    });

Using RowMapper in Spring 在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());
}

So, who call this mapRow method? 那么,谁调用这个mapRow方法呢? is it called automatically by the Spring Framework? 它是由Spring Framework自动调用的吗? (because in this example is never called manually...) (因为在这个例子中永远不会手动调用...)

This is automatically called by spring framework. 这是由spring框架自动调用的。 All You need is to specify 所有你需要的是指定

  1. Connection parameters, 连接参数,
  2. SQL statement SQL语句
  3. Declare parameters and provide parameter values 声明参数并提供参数值
  4. Do the work for each iteration. 为每次迭代做好工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM