Некоторые сомнения относительно использования RowMapper в JDBC в приложении Spring Framework

Я изучаю, как выполнить запрос к базе данных с помощью JDBC в Spring Framework.

Я следую этому руководству:http://www.tutorialspoint.com/spring/spring_jdbc_example.htm

в этом уроке я определяю StudentDAO интерфейс, который определяет только метод CRUD, который я хочу.

затем определяется студент класс, который является сущностью, которую я хочу сохранить в базе данных Student таблица.

затем определяется StudentMapper класс, который является конкретной реализацией RowMapper интерфейс, который в данном случае используется для отображения конкретной записи в ResultSet (ответ на запрос) к студент

4 ответов


когда вы передаете экземпляр RowMapper до JdbcTemplate метод

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

на JdbcTemplate в зависимости от того, какой метод вы вызвали, будет внутренне использовать mapper с результирующим набором, который он получает от соединения JDBC, чтобы создать объект запрошенного типа. Например, так как вы позвонили JdbcTemplate#query(String, RowMapper), метод будет использовать вашу строку 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 метод для создания ожидаемого возвращаемого объекта.

вы могли бы посмотреть на Мартина Фаулера Маппер Данных в сочетании с Табличный Шлюз Данных для представления о том, как эти вещи распределяются и обеспечивают низкие сцепные.


вот типичный шаблон, который я использую с 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;
        }
    });

использование 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());
}

Итак, кто вызывает этот метод mapRow? он вызывается автоматически Весенний Каркас? (потому что в этом примере никогда не вызывается вручную...)

это автоматически вызывается Spring framework. Все, что вам нужно, это указать

  1. параметры соединения,
  2. оператор SQL
  3. объявить параметры и предоставить значения параметров
  4. выполните работу для каждой итерации.