2013-02-27 5 views
15

Sto studiando come eseguire query su un database utilizzando JDBC in Spring Framework.Alcuni dubbi sull'uso di RowMapper in JDBC in un'applicazione Spring Framework

Sto seguendo questo tutorial: http://www.tutorialspoint.com/spring/spring_jdbc_example.htm

In questo tutorial definisco un StudentDAO interfaccia che definiscono solo il metodo CRUD che voglio.

Quindi è definita la classe Student che è l'entità che si desidera mantenere sulla tabella del database Studente.

Poi è definito il StudentMapper classe che è una specifica implementazione di RowMapper interfaccia che, in questo caso, viene utilizzato per mappare un record specifico nel ResultSet (restituito da una query) per un Studente oggetto.

allora ho il StudentJDBCTemplate che rappresentano l'implementazione della mia StudentDAO interfaccia , in questa classe a implementare il metodo CRUD che è stato definito nell'interfaccia.

Ok, e ora ho un dubbio su come il StudentMapper lavoro classe: in questo StudentJDBCTemplate classe ci viene definito il metodo che restituisce la lista di tutti i record che sono nella tabella del database Student, questo:

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

Come si può vedere, questo metodo restituisce un elenco di oggetti Student e il lavoro nel modo seguente:

la prima cosa che fanno è quello di definire la query che tornare tutto record nel St tabella database udent nella stringa SQL.

Poi questa ricerca viene eseguita dalla chiamata metodo di query sull'oggetto jdbcTemplateObject (cioè un'istanza di JdbcTemplate classe Spring **

Questo metodo prende due parametri: la stringa SQL (che contiene la query SQL che devono essere eseguite) e un nuovo StudentMapper oggetto che prende la ResultSet oggetto restituito dalla query e la mappa è record su un nuovo oggetto Student

Leggendo qua: http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html Sayas che: Ex ecuta una query con SQL statico, mappando ogni riga su un oggetto Java tramite RowMapper.

Il mio dubbio è legato al fatto che il mio StudentMapper mappa un record ResultSet su un oggetto Gli studenti, utilizzando il mapRow() metodo, questo è il codice:

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; 
    } 
} 

Quindi, che chiamano questo metodo mapRow? si chiama automaticamente dal Framework di primavera? (perché in questo esempio non viene mai chiamato manualmente ...)

Tnx

Andrea

Allora questa query viene eseguita dalla chiamata al metodo di query sull'oggetto jdbcTemplateObject (che è un istanza di JdbcTemplate classe Primavera **

risposta

22

Quando si passa un'istanza del RowMapper al JdbcTemplate metodo di

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

La JdbcTemplate a seconda di quale metodo hai chiamato, internamente utilizzerà il mapping con il set di risultati che riceve dal JDBC Connessione per creare un oggetto del tipo richiesto. Ad esempio, dal momento che hai chiamato JdbcTemplate#query(String, RowMapper), il metodo utilizza SQL String per interrogare il ciclo di database e la volontà attraverso ogni "riga" nel ResultSet un po 'come questo:

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; 

Quindi, Spring s' JdbcTemplate metodo sarà utilizzare lo RowMapper fornito e chiamare il suo metodo mapRow per creare l'oggetto di reso previsto.

Si potrebbe desiderare di guardare Martin Fowler Data Mapper in congiunzione con Table Data Gateway per un'idea di come queste cose sono distribuite e fornire low coupling.

1

Quindi, chi chiama questo metodo mapRow viene chiamato automaticamente dal framework Spring (perché in questo esempio non viene mai chiamato manualmente ...)

Questo viene chiamato automaticamente dalla struttura di primavera. Tutto quello che serve è quello di specificare

  1. Parametri di collegamento,
  2. SQL istruzione
  3. parametri dichiarare e fornire valori dei parametri
  4. fare il lavoro per ogni iterazione.
4

Ecco lo schema tipico che utilizzo con BeanPropertyRowMapper. Salva un sacco di codice. La tua query ha bisogno di alias ogni colonna per abbinare il nome della proprietà nella classe. In questo caso, species_name as species e gli altri nomi di colonna corrispondono già.

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; 
    } 
} 

Un'alternativa è quella di utilizzare un RowMapper (questo esempio utilizza solo una classe anonima) quando si ha bisogno di più di personalizzazione per riga:

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; 
     } 
    }); 
2

Utilizzando RowMapper nella primavera

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()); 
} 
Problemi correlati