mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-15 20:35:49 +00:00
#64 Remove N+1 select by using the OneToManyResultSetExtractor of Spring Data Core JDBC Extensions
This commit is contained in:
parent
08d55c975f
commit
818529b5b1
6 changed files with 111 additions and 33 deletions
14
pom.xml
14
pom.xml
|
@ -18,6 +18,7 @@
|
|||
<!-- Spring -->
|
||||
<spring-framework.version>4.1.6.RELEASE</spring-framework.version>
|
||||
<spring-data-jpa.version>1.8.0.RELEASE</spring-data-jpa.version>
|
||||
<spring-data-jdbc.version>1.1.0.RELEASE</spring-data-jdbc.version>
|
||||
|
||||
|
||||
<!-- Java EE / Java SE dependencies -->
|
||||
|
@ -127,6 +128,19 @@
|
|||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jdbc-core</artifactId>
|
||||
<version>${spring-data-jdbc.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
<!-- because Spring Data usually comes with a slightly older version of Spring -->
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
|
|
|
@ -116,18 +116,12 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
|
|||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("id", owner.getId().intValue());
|
||||
final List<JdbcPet> pets = this.namedParameterJdbcTemplate.query(
|
||||
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=:id",
|
||||
"SELECT pets.id, name, birth_date, type_id, owner_id, visits.id, visit_date, description, pet_id FROM pets LEFT OUTER JOIN visits ON pets.id = pet_id WHERE owner_id=:id",
|
||||
params,
|
||||
new JdbcPetRowMapper()
|
||||
new JdbcPetVisitExtractor()
|
||||
);
|
||||
for (JdbcPet pet : pets) {
|
||||
owner.addPet(pet);
|
||||
// Pet types have not been loaded at this stage. They are loaded separately
|
||||
pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
|
||||
List<Visit> visits = this.visitRepository.findByPetId(pet.getId());
|
||||
for (Visit visit : visits) {
|
||||
pet.addVisit(visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class JdbcPetRowMapper extends BeanPropertyRowMapper<JdbcPet> {
|
|||
@Override
|
||||
public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
|
||||
JdbcPet pet = new JdbcPet();
|
||||
pet.setId(rs.getInt("id"));
|
||||
pet.setId(rs.getInt("pets.id"));
|
||||
pet.setName(rs.getString("name"));
|
||||
Date birthDate = rs.getDate("birth_date");
|
||||
pet.setBirthDate(new DateTime(birthDate));
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.repository.jdbc;
|
||||
|
||||
import org.springframework.data.jdbc.core.OneToManyResultSetExtractor;
|
||||
import org.springframework.samples.petclinic.model.Visit;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class JdbcPetVisitExtractor extends
|
||||
OneToManyResultSetExtractor<JdbcPet, Visit, Integer> {
|
||||
|
||||
public JdbcPetVisitExtractor() {
|
||||
super(new JdbcPetRowMapper(), new JdbcVisitRowMapper());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer mapPrimaryKey(ResultSet rs) throws SQLException {
|
||||
return rs.getInt("pets.id");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer mapForeignKey(ResultSet rs) throws SQLException {
|
||||
if (rs.getObject("visits.pet_id") == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return rs.getInt("visits.pet_id");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addChild(JdbcPet root, Visit child) {
|
||||
root.addVisit(child);
|
||||
}
|
||||
}
|
|
@ -15,17 +15,8 @@
|
|||
*/
|
||||
package org.springframework.samples.petclinic.repository.jdbc;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
|
||||
|
@ -33,6 +24,9 @@ import org.springframework.samples.petclinic.model.Visit;
|
|||
import org.springframework.samples.petclinic.repository.VisitRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A simple JDBC-based implementation of the {@link VisitRepository} interface.
|
||||
*
|
||||
|
@ -90,21 +84,9 @@ public class JdbcVisitRepositoryImpl implements VisitRepository {
|
|||
|
||||
@Override
|
||||
public List<Visit> findByPetId(Integer petId) {
|
||||
final List<Visit> visits = this.jdbcTemplate.query(
|
||||
"SELECT id, visit_date, description FROM visits WHERE pet_id=?",
|
||||
new BeanPropertyRowMapper<Visit>() {
|
||||
@Override
|
||||
public Visit mapRow(ResultSet rs, int row) throws SQLException {
|
||||
Visit visit = new Visit();
|
||||
visit.setId(rs.getInt("id"));
|
||||
Date visitDate = rs.getDate("visit_date");
|
||||
visit.setDate(new DateTime(visitDate));
|
||||
visit.setDescription(rs.getString("description"));
|
||||
return visit;
|
||||
}
|
||||
},
|
||||
petId);
|
||||
return visits;
|
||||
return this.jdbcTemplate.query(
|
||||
"SELECT id as visit_id, visit_date, description FROM visits WHERE pet_id=?",
|
||||
new JdbcVisitRowMapper(), petId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.samples.petclinic.repository.jdbc;
|
||||
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.samples.petclinic.model.Visit;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
|
||||
class JdbcVisitRowMapper implements RowMapper<Visit> {
|
||||
|
||||
@Override
|
||||
public Visit mapRow(ResultSet rs, int row) throws SQLException {
|
||||
Visit visit = new Visit();
|
||||
visit.setId(rs.getInt("visits.id"));
|
||||
Date visitDate = rs.getDate("visit_date");
|
||||
visit.setDate(new DateTime(visitDate));
|
||||
visit.setDescription(rs.getString("description"));
|
||||
return visit;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue