package org.springframework.samples.petclinic.jdbc; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.sql.DataSource; import javax.jws.WebService; import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.PathParam; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper; import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.samples.petclinic.Clinic; import org.springframework.samples.petclinic.Owner; import org.springframework.samples.petclinic.Pet; import org.springframework.samples.petclinic.PetType; import org.springframework.samples.petclinic.Specialty; import org.springframework.samples.petclinic.Vet; import org.springframework.samples.petclinic.Visit; import org.springframework.samples.petclinic.util.EntityUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * A simple JDBC-based implementation of the {@link Clinic} interface. * *
This class uses Java 5 language features and the {@link SimpleJdbcTemplate} * plus {@link SimpleJdbcInsert}. It also takes advantage of classes like * {@link BeanPropertySqlParameterSource} and * {@link ParameterizedBeanPropertyRowMapper} which provide automatic mapping * between JavaBean properties and JDBC parameters or query results. * *
SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base
* class for JDBC implementations of the Clinic interface for Spring 2.0.
*
* @author Ken Krebs
* @author Juergen Hoeller
* @author Rob Harrop
* @author Sam Brannen
* @author Thomas Risberg
* @author Mark Fisher
*/
@Service
@ManagedResource("petclinic:type=Clinic")
@Path ( "/clinic" )
@WebService (
endpointInterface = "org.springframework.samples.petclinic.Clinic"
)
public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
private final Log logger = LogFactory.getLog(getClass());
private SimpleJdbcTemplate simpleJdbcTemplate;
private SimpleJdbcInsert insertOwner;
private SimpleJdbcInsert insertPet;
private SimpleJdbcInsert insertVisit;
private final Listid; also loads
* the {@link Pet Pets} and {@link Visit Visits} for the corresponding
* owner, if not already loaded.
*/
@Transactional(readOnly = true)
public Owner loadOwner(int id) throws DataAccessException {
Owner owner;
try {
owner = this.simpleJdbcTemplate.queryForObject(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id=?",
ParameterizedBeanPropertyRowMapper.newInstance(Owner.class),
id);
}
catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Owner.class, new Integer(id));
}
loadPetsAndVisits(owner);
return owner;
}
@Transactional(readOnly = true)
public Pet loadPet(int id) throws DataAccessException {
JdbcPet pet;
try {
pet = this.simpleJdbcTemplate.queryForObject(
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=?",
new JdbcPetRowMapper(),
id);
}
catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Pet.class, new Integer(id));
}
Owner owner = loadOwner(pet.getOwnerId());
owner.addPet(pet);
pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
loadVisits(pet);
return pet;
}
@Transactional
public void storeOwner(Owner owner) throws DataAccessException {
if (owner.isNew()) {
Number newKey = this.insertOwner.executeAndReturnKey(
new BeanPropertySqlParameterSource(owner));
owner.setId(newKey.intValue());
}
else {
this.simpleJdbcTemplate.update(
"UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
"city=:city, telephone=:telephone WHERE id=:id",
new BeanPropertySqlParameterSource(owner));
}
}
@Transactional
public void storePet(Pet pet) throws DataAccessException {
if (pet.isNew()) {
Number newKey = this.insertPet.executeAndReturnKey(
createPetParameterSource(pet));
pet.setId(newKey.intValue());
}
else {
this.simpleJdbcTemplate.update(
"UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " +
"owner_id=:owner_id WHERE id=:id",
createPetParameterSource(pet));
}
}
@Transactional
public void storeVisit(Visit visit) throws DataAccessException {
if (visit.isNew()) {
Number newKey = this.insertVisit.executeAndReturnKey(
createVisitParameterSource(visit));
visit.setId(newKey.intValue());
}
else {
throw new UnsupportedOperationException("Visit update not supported");
}
}
// END of Clinic implementation section ************************************
/**
* Creates a {@link MapSqlParameterSource} based on data values from the
* supplied {@link Pet} instance.
*/
private MapSqlParameterSource createPetParameterSource(Pet pet) {
return new MapSqlParameterSource()
.addValue("id", pet.getId())
.addValue("name", pet.getName())
.addValue("birth_date", pet.getBirthDate())
.addValue("type_id", pet.getType().getId())
.addValue("owner_id", pet.getOwner().getId());
}
/**
* Creates a {@link MapSqlParameterSource} based on data values from the
* supplied {@link Visit} instance.
*/
private MapSqlParameterSource createVisitParameterSource(Visit visit) {
return new MapSqlParameterSource()
.addValue("id", visit.getId())
.addValue("visit_date", visit.getDate())
.addValue("description", visit.getDescription())
.addValue("pet_id", visit.getPet().getId());
}
/**
* Loads the {@link Visit} data for the supplied {@link Pet}.
*/
private void loadVisits(JdbcPet pet) {
final List