- A Practical Case -
Introduction
Its not always obvious to simply understand a concept Facing a concrete situation helps to clearly and straightforwardly understand
What is the concept about ? Why is it used ?
Prerequisites
You should be familiar with:
Java JDBC (PreparedStatement ) SQL Design Patterns (DAO )
Scenario
Lets consider two classes:
Person Car
A person owns many cars A car is owned by one and only one person
Scenario
Imagine we will implement the following scenario
Display a list of persons Select one person
Display person details
Scenario
4- Detail Car 1- List Persons
3- List Cars
2- Detail Person
Person
private private private private private BigDecimal id; String firstName; String lastName; String email; List<Car> cars;
public Person(); public Person(ResultSet); public public public public public public public public public public BigDecimal getId(); void setId(BigDecimal); String getFirstName(); void setFirstName(String); String getLastName(); void setLastName(String); String getEmail(); void setEmail(String); List<Car> getCars(); void setCars(List<Car>);
Car
private String name; private BigDecimal model; private String plateNumber;
public Car(); public Car(ResultSet); public public public public public public String getName(); void setName(String); BigDecimal getModel(); void setModel(BigDecimal); String getPlateNumber(); void setPlateNumber (String);
public class Person { private BigDecimal id; private String firstName; private String lastName; private String email; private List<Cars> cars; /* * Default Constructor. */ public Person() { this.id = null; this.firstName = ; this.lastName = ; this.email = ; this.cars = null; } /* * Constructor with ResultSet. */ public Person(ResultSet rs) { this.id = rs.getBigDecimal(ID_PERSON); this.firstName = rs.getString(FIRST_NAME); this.lastName = rs.getString(LAST_NAME); this.email = rs.getString(EMAIL); this.cars = null; } /* * Getters & Setters */ }
public class CarDAO extends DAO<Car> { public List<Car> getByPerson(BigDecimal id) { StringBuilder sql = new StringBuilder(); sql.append( SELECT sql.append( FROM sql.append( WHERE * ); CAR ); ID_PERS = ?);
PreparedStatement ps = this.getConnection().prepareStatement(sql.toString()); ps.setBigDecimal(1, id); ResultSet rs = requeteSQL.executeQuery(); List<Car> cars = new ArrayList<Car>(); while (rs.next()) { cars.add(new Car(rs)); } return cars;
}
}
public class PersonDAO extends DAO<Person> { public Person getByID(BigDecimal id) { StringBuilder sql = new StringBuilder(); sql.append( sql.append( sql.append( sql.append( sql.append( SELECT FROM JOIN ON WHERE * ); PERSON CAR p.ID_PERS p.ID_PERS
p c = =
); ); c.ID_PERS ); ?);
PreparedStatement ps = this.getConnection().prepareStatement(sql.toString()); ps.setBigDecimal(1, id); ResultSet rs = requeteSQL.executeQuery(); Person person = null; if (rs.next()) { person = new Person(rs); CarDAO carDAO = DAOFactory.getCarDAO(); List<Car> cars = carDAO.getByPerson(person.getId()); person.setCars(cars); } return person; } }
public class PersonDAO extends DAO<Person> { public List<Person> getAll() { StringBuilder sql = new StringBuilder(); sql.append( sql.append( sql.append( sql.append( SELECT FROM JOIN ON * ); PERSON p ); CAR c ); p.ID_PERS = c.ID_PERS );
PreparedStatement ps = this.getConnection().prepareStatement(sql.toString()); ResultSet rs = requeteSQL.executeQuery(); List<Person> persons = new ArrayList<Person>(); while (rs.next()) { Person p = new Person(rs); CarDAO carDAO = DAOFactory.getCarDAO(); List<Car> cars = carDAO.getCarsByPerson(person.getId()); p.setCars(cars); persons.add(p); } return persons; }
PersonList
private List<Person> persons; public PersonList(); public PersonList(ResultSet);
CarList
private List<Car> cars; public CarList(); public CarList(ResultSet); public List<Car> getCars(); public void setCars(List<Car>); public List<Car> search(String); public void sort();
/* * Constructor with ResultSet. */ Public PersonList(ResultSet rs) { [] while (rs.next) { this.persons.add(new Person(rs)); } [] } /* * Constructor with ResultSet. */ Public CarList(ResultSet rs) { [] while (rs.next) { this.cars.add(new Car(rs)); } [] }
public Person(); public Person(ResultSet rs); public public public public public public public public public public BigDecimal getId(); void setId(BigDecimal); String getFirstName(); void setFirstName(String); String getLastName(); void setLastName(String); String getEmail(); void setEmail(String); CarList getCars(); void setCars(CarList);
<<abstract>> EntityList<T>
private List<T> aList; Public EntityList(); Public EntityList(ResultSet);
public abstract List<T> search(String); public abstract void sort();
PersonList<Person>
public PersonList(); public PersonList(ResultSet);
CarList<Car>
public CarList(); public CarList(ResultSet);
/* * Constructor with ResultSet. */ public void PersonList(ResultSet rs) { super(rs); } /* * Constructor with ResultSet. */ public void CarList(ResultSet rs) { super(rs); }
Conclusion
Absolute code reusability Usage of abstraction as most as possible
flexibility
Design Pattern
Custom List Wrapper? Imposes a top/down structure
abstract classes/interfaces