Some doubts about RowMapper use in JDBC in a Spring Framework application

后端 未结 4 1639
悲哀的现实
悲哀的现实 2021-02-07 10:17

I am studying how to execute query on a database using JDBC in Spring Framework.

I am following this tutorial: http://www.tutorialspoint.com/spring/spring_jdbc_example.h

相关标签:
4条回答
  • 2021-02-07 10:56

    Here is the typical pattern I use with 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.

    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:

        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;
            }
        });
    
    0 讨论(0)
  • 2021-02-07 11:01

    When you pass an instance of your RowMapper to the JdbcTemplate method

    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. 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:

    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.

    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.

    0 讨论(0)
  • 2021-02-07 11:01

    So, who call this mapRow method? is it called automatically by the Spring Framework? (because in this example is never called manually...)

    This is automatically called by spring framework. All You need is to specify

    1. Connection parameters,
    2. SQL statement
    3. Declare parameters and provide parameter values
    4. Do the work for each iteration.
    0 讨论(0)
  • Using RowMapper in Spring

    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());
    }
    
    0 讨论(0)
提交回复
热议问题