SimpleJdbcClinic.java
资源名称:petclinic.rar [点击查看]
上传用户:dezhong
上传日期:2022-08-10
资源大小:167k
文件大小:12k
源码类别:
Java编程
开发平台:
Java
- 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 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.
- *
- * <p>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.
- *
- * <p>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")
- 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 List<Vet> vets = new ArrayList<Vet>();
- @Autowired
- public void init(DataSource dataSource) {
- this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
- this.insertOwner = new SimpleJdbcInsert(dataSource)
- .withTableName("owners")
- .usingGeneratedKeyColumns("id");
- this.insertPet = new SimpleJdbcInsert(dataSource)
- .withTableName("pets")
- .usingGeneratedKeyColumns("id");
- this.insertVisit = new SimpleJdbcInsert(dataSource)
- .withTableName("visits")
- .usingGeneratedKeyColumns("id");
- }
- /**
- * Refresh the cache of Vets that the Clinic is holding.
- * @see org.springframework.samples.petclinic.Clinic#getVets()
- */
- @ManagedOperation
- @Transactional(readOnly = true)
- public void refreshVetsCache() throws DataAccessException {
- synchronized (this.vets) {
- this.logger.info("Refreshing vets cache");
- // Retrieve the list of all vets.
- this.vets.clear();
- this.vets.addAll(this.simpleJdbcTemplate.query(
- "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
- ParameterizedBeanPropertyRowMapper.newInstance(Vet.class)));
- // Retrieve the list of all possible specialties.
- final List<Specialty> specialties = this.simpleJdbcTemplate.query(
- "SELECT id, name FROM specialties",
- ParameterizedBeanPropertyRowMapper.newInstance(Specialty.class));
- // Build each vet's list of specialties.
- for (Vet vet : this.vets) {
- final List<Integer> vetSpecialtiesIds = this.simpleJdbcTemplate.query(
- "SELECT specialty_id FROM vet_specialties WHERE vet_id=?",
- new ParameterizedRowMapper<Integer>() {
- public Integer mapRow(ResultSet rs, int row) throws SQLException {
- return Integer.valueOf(rs.getInt(1));
- }},
- vet.getId().intValue());
- for (int specialtyId : vetSpecialtiesIds) {
- Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
- vet.addSpecialty(specialty);
- }
- }
- }
- }
- // START of Clinic implementation section *******************************
- @Transactional(readOnly = true)
- public Collection<Vet> getVets() throws DataAccessException {
- synchronized (this.vets) {
- if (this.vets.isEmpty()) {
- refreshVetsCache();
- }
- return this.vets;
- }
- }
- @Transactional(readOnly = true)
- public Collection<PetType> getPetTypes() throws DataAccessException {
- return this.simpleJdbcTemplate.query(
- "SELECT id, name FROM types ORDER BY name",
- ParameterizedBeanPropertyRowMapper.newInstance(PetType.class));
- }
- /**
- * Loads {@link Owner Owners} from the data store by last name, returning
- * all owners whose last name <i>starts</i> with the given name; also loads
- * the {@link Pet Pets} and {@link Visit Visits} for the corresponding
- * owners, if not already loaded.
- */
- @Transactional(readOnly = true)
- public Collection<Owner> findOwners(String lastName) throws DataAccessException {
- List<Owner> owners = this.simpleJdbcTemplate.query(
- "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like ?",
- ParameterizedBeanPropertyRowMapper.newInstance(Owner.class),
- lastName + "%");
- loadOwnersPetsAndVisits(owners);
- return owners;
- }
- /**
- * Loads the {@link Owner} with the supplied <code>id</code>; 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<Visit> visits = this.simpleJdbcTemplate.query(
- "SELECT id, visit_date, description FROM visits WHERE pet_id=?",
- new ParameterizedRowMapper<Visit>() {
- public Visit mapRow(ResultSet rs, int row) throws SQLException {
- Visit visit = new Visit();
- visit.setId(rs.getInt("id"));
- visit.setDate(rs.getTimestamp("visit_date"));
- visit.setDescription(rs.getString("description"));
- return visit;
- }
- },
- pet.getId().intValue());
- for (Visit visit : visits) {
- pet.addVisit(visit);
- }
- }
- /**
- * Loads the {@link Pet} and {@link Visit} data for the supplied
- * {@link Owner}.
- */
- private void loadPetsAndVisits(final Owner owner) {
- final List<JdbcPet> pets = this.simpleJdbcTemplate.query(
- "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=?",
- new JdbcPetRowMapper(),
- owner.getId().intValue());
- for (JdbcPet pet : pets) {
- owner.addPet(pet);
- pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
- loadVisits(pet);
- }
- }
- /**
- * Loads the {@link Pet} and {@link Visit} data for the supplied
- * {@link List} of {@link Owner Owners}.
- *
- * @param owners the list of owners for whom the pet and visit data should be loaded
- * @see #loadPetsAndVisits(Owner)
- */
- private void loadOwnersPetsAndVisits(List<Owner> owners) {
- for (Owner owner : owners) {
- loadPetsAndVisits(owner);
- }
- }
- /**
- * {@link ParameterizedRowMapper} implementation mapping data from a
- * {@link ResultSet} to the corresponding properties of the {@link JdbcPet} class.
- */
- private class JdbcPetRowMapper implements ParameterizedRowMapper<JdbcPet> {
- public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
- JdbcPet pet = new JdbcPet();
- pet.setId(rs.getInt("id"));
- pet.setName(rs.getString("name"));
- pet.setBirthDate(rs.getDate("birth_date"));
- pet.setTypeId(rs.getInt("type_id"));
- pet.setOwnerId(rs.getInt("owner_id"));
- return pet;
- }
- }
- }