Skip to content

Commit

Permalink
Merge pull request #109 from spring-petclinic/feature/103-jdbc-client
Browse files Browse the repository at this point in the history
Migrate Jdbc DAO from RestTemplate to JdbcClient #103
  • Loading branch information
arey authored Dec 29, 2023
2 parents 54aab95 + 7627170 commit 3d71ba6
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 111 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples</groupId>
<artifactId>spring-framework-petclinic</artifactId>
<version>6.0.15</version>
<version>6.1.2</version>

<name>Spring Framework Petclinic</name>
<packaging>war</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,11 @@
*/
package org.springframework.samples.petclinic.repository.jdbc;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.samples.petclinic.model.Owner;
Expand All @@ -37,6 +30,10 @@
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.util.Collection;
import java.util.List;

/**
* A simple JDBC-based implementation of the {@link OwnerRepository} interface.
*
Expand All @@ -51,18 +48,18 @@
@Repository
public class JdbcOwnerRepositoryImpl implements OwnerRepository {

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final JdbcClient jdbcClient;

private SimpleJdbcInsert insertOwner;
private final SimpleJdbcInsert insertOwner;

@Autowired
public JdbcOwnerRepositoryImpl(DataSource dataSource) {
public JdbcOwnerRepositoryImpl(DataSource dataSource, JdbcClient jdbcClient) {

this.insertOwner = new SimpleJdbcInsert(dataSource)
.withTableName("owners")
.usingGeneratedKeyColumns("id");

this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.jdbcClient = jdbcClient;

}

Expand All @@ -74,13 +71,14 @@ public JdbcOwnerRepositoryImpl(DataSource dataSource) {
*/
@Override
public Collection<Owner> findByLastName(String lastName) {
Map<String, Object> params = new HashMap<>();
params.put("lastName", lastName + "%");
List<Owner> owners = this.namedParameterJdbcTemplate.query(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName",
params,
BeanPropertyRowMapper.newInstance(Owner.class)
);
List<Owner> owners = this.jdbcClient.sql("""
SELECT id, first_name, last_name, address, city, telephone
FROM owners
WHERE last_name like :lastName
""")
.param("lastName", lastName + "%")
.query(BeanPropertyRowMapper.newInstance(Owner.class))
.list();
loadOwnersPetsAndVisits(owners);
return owners;
}
Expand All @@ -93,13 +91,13 @@ public Collection<Owner> findByLastName(String lastName) {
public Owner findById(int id) {
Owner owner;
try {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
owner = this.namedParameterJdbcTemplate.queryForObject(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id",
params,
BeanPropertyRowMapper.newInstance(Owner.class)
);
owner = this.jdbcClient.sql("""
SELECT id, first_name, last_name, address, city, telephone
FROM owners WHERE id = :id
""")
.param("id", id)
.query(BeanPropertyRowMapper.newInstance(Owner.class))
.single();
} catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Owner.class, id);
}
Expand All @@ -108,13 +106,13 @@ public Owner findById(int id) {
}

public void loadPetsAndVisits(final Owner owner) {
Map<String, Object> params = new HashMap<>();
params.put("id", owner.getId());
final List<JdbcPet> pets = this.namedParameterJdbcTemplate.query(
"SELECT pets.id, name, birth_date, type_id, owner_id, visits.id as visit_id, visit_date, description, pet_id FROM pets LEFT OUTER JOIN visits ON pets.id = pet_id WHERE owner_id=:id ORDER BY pet_id",
params,
new JdbcPetVisitExtractor()
);
final List<JdbcPet> pets = this.jdbcClient.sql("""
SELECT pets.id, name, birth_date, type_id, owner_id, visits.id as visit_id, visit_date, description, pet_id
FROM pets LEFT OUTER JOIN visits ON pets.id = pet_id
WHERE owner_id=:id ORDER BY pet_id
""")
.param("id", owner.getId())
.query(new JdbcPetVisitExtractor());
Collection<PetType> petTypes = getPetTypes();
for (JdbcPet pet : pets) {
pet.setType(EntityUtils.getById(petTypes, PetType.class, pet.getTypeId()));
Expand All @@ -129,17 +127,20 @@ public void save(Owner owner) {
Number newKey = this.insertOwner.executeAndReturnKey(parameterSource);
owner.setId(newKey.intValue());
} else {
this.namedParameterJdbcTemplate.update(
"UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
"city=:city, telephone=:telephone WHERE id=:id",
parameterSource);
this.jdbcClient.sql("""
UPDATE owners
SET first_name=:firstName, last_name=:lastName, address=:address, city=:city, telephone=:telephone
WHERE id=:id
""")
.paramSource(parameterSource)
.update();
}
}

public Collection<PetType> getPetTypes() {
return this.namedParameterJdbcTemplate.query(
"SELECT id, name FROM types ORDER BY name", new HashMap<String, Object>(),
BeanPropertyRowMapper.newInstance(PetType.class));
return this.jdbcClient.sql("SELECT id, name FROM types ORDER BY name")
.query(BeanPropertyRowMapper.newInstance(PetType.class))
.list();
}

/**
Expand All @@ -154,5 +155,4 @@ private void loadOwnersPetsAndVisits(List<Owner> owners) {
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@
*/
package org.springframework.samples.petclinic.repository.jdbc;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.samples.petclinic.model.Owner;
Expand All @@ -36,26 +30,30 @@
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.util.List;

/**
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
* @author Antoine Rey
*/
@Repository
public class JdbcPetRepositoryImpl implements PetRepository {

private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private final JdbcClient jdbcClient;

private SimpleJdbcInsert insertPet;
private final SimpleJdbcInsert insertPet;

private OwnerRepository ownerRepository;
private final OwnerRepository ownerRepository;

@Autowired
public JdbcPetRepositoryImpl(DataSource dataSource, OwnerRepository ownerRepository) {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
public JdbcPetRepositoryImpl(JdbcClient jdbcClient, DataSource dataSource, OwnerRepository ownerRepository) {
this.jdbcClient = jdbcClient;

this.insertPet = new SimpleJdbcInsert(dataSource)
.withTableName("pets")
Expand All @@ -66,20 +64,21 @@ public JdbcPetRepositoryImpl(DataSource dataSource, OwnerRepository ownerReposit

@Override
public List<PetType> findPetTypes() {
Map<String, Object> params = new HashMap<>();
return this.namedParameterJdbcTemplate.query(
"SELECT id, name FROM types ORDER BY name",
params,
BeanPropertyRowMapper.newInstance(PetType.class));
return this.jdbcClient
.sql("SELECT id, name FROM types ORDER BY name")
.query(BeanPropertyRowMapper.newInstance(PetType.class))
.list();
}

@Override
public Pet findById(int id) {
Integer ownerId;
int ownerId;
try {
Map<String, Object> params = new HashMap<>();
params.put("id", id);
ownerId = this.namedParameterJdbcTemplate.queryForObject("SELECT owner_id FROM pets WHERE id=:id", params, Integer.class);
ownerId = this.jdbcClient
.sql("SELECT owner_id FROM pets WHERE id=:id")
.param("id", id)
.query(Integer.class)
.single();
} catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Pet.class, id);
}
Expand All @@ -94,10 +93,14 @@ public void save(Pet pet) {
createPetParameterSource(pet));
pet.setId(newKey.intValue());
} else {
this.namedParameterJdbcTemplate.update(
"UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " +
"owner_id=:owner_id WHERE id=:id",
createPetParameterSource(pet));
this.jdbcClient
.sql("""
UPDATE pets
SET name=:name, birth_date=:birth_date, type_id=:type_id, owner_id=:owner_id
WHERE id=:id
""")
.paramSource(createPetParameterSource(pet))
.update();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@
*/
package org.springframework.samples.petclinic.repository.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.samples.petclinic.model.Specialty;
import org.springframework.samples.petclinic.model.Vet;
import org.springframework.samples.petclinic.repository.VetRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
* A simple JDBC-based implementation of the {@link VetRepository} interface.
*
Expand All @@ -40,44 +40,47 @@
* @author Thomas Risberg
* @author Mark Fisher
* @author Michael Isvy
* @author Antoine Rey
*/
@Repository
public class JdbcVetRepositoryImpl implements VetRepository {

private JdbcTemplate jdbcTemplate;
private final JdbcClient jdbcClient;

@Autowired
public JdbcVetRepositoryImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
public JdbcVetRepositoryImpl(JdbcClient jdbcClient) {
this.jdbcClient = jdbcClient;
}

/**
* Refresh the cache of Vets that the ClinicService is holding.
*/
@Override
public Collection<Vet> findAll() {
List<Vet> vets = new ArrayList<>();
// Retrieve the list of all vets.
vets.addAll(this.jdbcTemplate.query(
"SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
BeanPropertyRowMapper.newInstance(Vet.class)));
List<Vet> vets = new ArrayList<>(this.jdbcClient.sql(
"SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name")
.query(BeanPropertyRowMapper.newInstance(Vet.class))
.list());

// Retrieve the list of all possible specialties.
final List<Specialty> specialties = this.jdbcTemplate.query(
"SELECT id, name FROM specialties",
BeanPropertyRowMapper.newInstance(Specialty.class));
final List<Specialty> specialties = this.jdbcClient.sql("SELECT id, name FROM specialties")
.query(BeanPropertyRowMapper.newInstance(Specialty.class))
.list();

// Build each vet's list of specialties.
for (Vet vet : vets) {
final List<Integer> vetSpecialtiesIds = this.jdbcTemplate.query(
"SELECT specialty_id FROM vet_specialties WHERE vet_id=?",
new BeanPropertyRowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int row) throws SQLException {
return rs.getInt(1);
final List<Integer> vetSpecialtiesIds = this.jdbcClient.sql(
"SELECT specialty_id FROM vet_specialties WHERE vet_id=?")
.param(vet.getId())
.query(
new BeanPropertyRowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int row) throws SQLException {
return rs.getInt(1);
}
}
},
vet.getId());
).list();
for (int specialtyId : vetSpecialtiesIds) {
Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
vet.addSpecialty(specialty);
Expand Down
Loading

0 comments on commit 3d71ba6

Please sign in to comment.