patrón DAO explicado por Peter

Las aplicaciones que gestionan datos de cualquier tipo necesitan acceder a repositorios de datos persistentes como las BBDD. Los datos no siempre tienen por qué estar en  una BD relacional a la que se accede por JDBC, es más, puede que la BD cambie o que incluso hay otro tipo de orígenes de datos como un LDAP. Con el objeto de separar la lógica de negocio con los detalles de acceso a los datos es habitual aplicar este patrón.

Todas las operaciones se hacen a través de una clase DAO que implementa todas las operaciones necesarias para gestionar determinados datos (CRUD + lo que haga falta). Esa clase DAO conoce los detalles del origen de los datos e incluso utiliza otra clase para gestionar el acceso a los mismos.

Para intercambiar información entre el DAO y la aplicación se utilizan objetos que representan los datos que se sacan del origen de datos, comúnmente suelen ser clases que representan una tabla de una BBDD.

Este es un ejemplo con una BBDD llamada ERP que contiene una tabla llamada Customer. 

Aplicando el patrón utilizaremos las siguientes clases:

  • Customer: representa los datos de la tabla y se utiliza para intercambiar información entre el programa y la clase DAO.
  • CustomerDAO: se encarga de todas las operaciones CRUD.
  • DataSource: se encarga de conseguir la conexión con el origen de datos.
  • Main: el programa que hace uso del CustomerDAO para interactuar con los datos persistentes.

Customer

 

/**
 * POJO class for Customer
 * @author Pello Altadill
 *
 */
public class Customer {
private int id;
private String name;
private String address;
 
/**
* @param id
* @param name
* @param address
*/
public Customer(int id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
 
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address
+ "]";
}
 
 
/********** Getters/Setters ********************/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
 
}
 

CustomerDAO

 

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 
 */
 
/**
 * @author Pello Altadill
 *
 */
public class CustomerDAO {
DataSource dataSource = new DataSource();
 
/**
* gets Customer data from DataBase
* @param customerId
* @return
*/
public Customer read (int customerId) {
Customer customer = null;
String name = "";
String address = "";
String sql = "select * from customer where id=" + customerId;
Connection connection = dataSource.getConnection();
try {
Statement statement =  connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
 
if (resultSet.next()) {
name = resultSet.getString("name");
address = resultSet.getString("address");
customer = new Customer(customerId, name, address);
} catch (Exception e) {
System.err.println("Exception: " +  sql + ". Error: " + e.getMessage());
return customer;
 
/**
* gets all Customer data from DataBase
* @return list of customers
*/
public List readAll () {
 
List customerList = new ArrayList();
int id = 0;
String name = "";
String address = "";
String sql = "select * from customer";
Connection connection = dataSource.getConnection();
try {
Statement statement =  connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
 
while (resultSet.next()) {
id = resultSet.getInt("id");
name = resultSet.getString("name");
address = resultSet.getString("address");
customerList.add(new Customer(id, name, address));
} catch (Exception e) {
System.err.println("Exception: " +  sql + ". Error: " + e.getMessage());
return customerList;
 
/**
* creates new Customer
* @param newCustomer
* @return
*/
public int create (Customer newCustomer) {
String sql = "insert into customer (name, address) values ('"+newCustomer.getName()+"','"+newCustomer.getAddress()+"')";
Connection connection = null;
Statement statement = null;
int result = 0;
 
try {
connection = dataSource.getConnection();
   statement = connection.createStatement();
   result = statement.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS);
   
   // try to get generated key
   ResultSet rs = statement.getGeneratedKeys();
   if (rs.next()){
       result=rs.getInt(1);
   }
   
   System.out.println("[DataService] create> " + sql);
 
} catch (SQLException e) {
System.err.println("Exception: " +  sql + ". Error: " + e.getMessage());
} finally {
}
   return result;
}
 
/**
* updates customer information 
* @param customer
* @return
*/
public int update (Customer customer) {
String sql = "update customer set name='"+customer.getName()+"',address='"+customer.getAddress()+"' where id="+customer.getId();
Connection connection = null;
Statement statement = null;
int result = 0;
 
try {
connection = dataSource.getConnection();
   statement = connection.createStatement();
   result = statement.executeUpdate(sql);
   System.out.println("[DataService] update> " + sql);
} catch (SQLException e) {
System.err.println("Exception: " +  sql + ". Error: " + e.getMessage());
} finally {
}
   return result;
}
 
/**
* delete customer  
* @param customerId
* @return
*/
public int delete (int customerId) {
String sql = "delete from customer where id="+customerId;
Connection connection = null;
Statement statement = null;
int result = 0;
 
try {
connection = dataSource.getConnection();
   statement = connection.createStatement();
   result = statement.executeUpdate(sql);
   System.out.println("[DataService] delete> " + sql);
} catch (SQLException e) {
System.err.println("Exception: " +  sql + ". Error: " + e.getMessage());
} finally {
}
   return result;
}
 
}
 

DataSource

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
/**
 * This class provides access to a DataSource
 * and is used by DAO classes to get the Connection instance
 * @author Pello Altadill
 *
 */
public class DataSource {
 
private String dbUrl;
private String login;
private String password;
private String driver;
private Connection connection;
 
/**
* constructor for DataService
* opens connection to DataSource
* uses default dbUrl
*/
public DataSource () {
this.dbUrl = "jdbc:mysql://localhost:3306/erp";
this.login = "root";
this.password = "root";
this.driver = "com.mysql.jdbc.Driver";
openDataSource();
}
 
/**
* constructor for DataService
* @param dbUrl url to database
*/
public DataSource (String dbUrl, String login, String password, String driver) {
this.dbUrl = dbUrl;
this.login = login;
this.password = password;
this.driver = driver;
openDataSource();
}
 
/**
* opens connection to DataSource
*/
private void openDataSource() {
try {
Class.forName(this.driver);
connection = DriverManager.getConnection(this.dbUrl, this.login, this.password);
} catch (SQLException sqle) {
System.err.println("Connection error: " + sqle.getMessage());
} catch (Exception e) {
System.err.println("Connection error: " + e.getMessage());
}
}
 
/**
* returns current opened connection to DataSource
* @return Connection instance
*/
public Connection getConnection () {
return connection;
}
 
/**
* closes DataSource connection
*/
public void close () {
try {
connection.close();
} catch (SQLException sqle) {
System.err.println("Connection error: " + sqle.getMessage());
} catch (Exception e) {
System.err.println("Connection error: " + e.getMessage());
}
}
 
 
}
 

Main

import java.util.Scanner;

 
 
/**
 * @author luser
 *
 */
public class Main {
 
/**
* @param args
*/
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
CustomerDAO customerDAO = new CustomerDAO();
 
// TODO Auto-generated method stub
int id = 0;
String name = "";
String address = "";
 
// CREATE
System.out.println("Insert new Name");
name = scanner.nextLine();
System.out.println("Insert new Adress");
address = scanner.nextLine();
 
Customer customer = new Customer(0, name, address);
int newId = customerDAO.create(customer);
 
customer.setId(newId);
 
System.out.println("Customer data: " + customer.toString());
 
// UPDATE DATA
System.out.println("Insert new Name");
name = scanner.nextLine();
System.out.println("Insert new Adress");
address = scanner.nextLine();
 
customer.setName(name);
customer.setAddress(address);
customerDAO.update(customer);
 
// REMOVE
customerDAO.delete(customer.getId());
 
}
 
}
 

El DAO pattern de la mano de Oracle

Diagrama del patrón DAO