Skip to content
Snippets Groups Projects
Commit 818529b5 authored by Antoine Rey's avatar Antoine Rey
Browse files

#64 Remove N+1 select by using the OneToManyResultSetExtractor of Spring Data Core JDBC Extensions

parent 08d55c97
No related branches found
No related tags found
No related merge requests found
......@@ -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));
......
/*
* 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);
}
}
\ No newline at end of file
......@@ -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);
}
}
/*
* 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;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment