Data Access Object (DAO) con JDBC

Este tutorial nos enseña cómo implementar el patrón de diseño DAO en una aplicación Java conectada mediante la API Java Database Connectivity (JDBC), el patrón DAO busca crear una separación entre las capas de bajo nivel (acceso a datos) y la capa de alto nivel (servicios de negocios).

Iniciar base de datos


Usaremos el motor de bases de datos HSQLDB, descargamos y extraemos la carpeta hsqldb-2.3.3, iniciamos el archivo de comandos hsqldb/runServer.bat, este iniciar el servidor y crea una base datos llamada test almacenada en el directorio hsqldb/data, no cerrar la ventana esto detiene el servidor, para crear las tablas ejecutamos el batch hsqldb/runManagerSwing.bat, indicamos que nos conectaremos al servidor.

hsqldb connectar servidor
Usaremos los datos de prueba proporcionados por la aplicación.

hsqldb insert data
Necesitamos actualizar la vista, vamos a View/Refresh Tree (Ctrl + R).

jdbc datos

Creación del DAO


Usaremos la tabla PRODUCT de la base de datos que acabamos de crear, por lo que requerimos de una clase para representar esta tabla, asociaremos cada una de sus columnas a un campo correspondiente de la clase, la llamaremos Product.

public class Product {

    private Integer id;
    private String name;
    private Double price;

    public Product(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    //... getter y setter omitidos ...//
}

La interfaz ProductDao contara con las operaciones básicas: insertar, leer, actualizar y eliminar un producto.

public interface ProductDao {
    public void insert(Product product);
    public void update(Product product);
    public void delete(Integer id);
    public Product read(Integer id);
}

La clase ProductDaoImpl será la encargada de implementar la funcionalidad establecida por la interfaz ProductDao, usaremos la API JDBC para realizar estas operaciones sobre la base de datos.

Primero que nada debemos agregar la librería hsqldb.jar a nuestro proyecto, hacemos lo siguiente: En Netbeans 8 ubicamos el proyecto en la pestaña Projects, expandimos la vista, hacemos clic derecho sobre Libraries opción Add JAR/Folder… seleccionamos el archivo hsqldb.jar que se encuentra en la carpeta hsqldb/lib que extrajimos anteriormente.

agregar hsqldb a netbeans
Nuestro proyecto está estructurado de la siguiente manera:

patron dao
La clase ProductDaoImpl será la encargada de implementar la funcionalidad establecida por la interfaz ProductDao, usaremos la API JDBC para realizar estas operaciones sobre la base de datos.

Primero que nada debemos agregar la librería hsqldb.jar a nuestro proyecto, hacemos lo siguiente: En Netbeans 8 ubicamos el proyecto en la pestaña Projects, expandimos la vista, hacemos clic derecho sobre Libraries opción Add JAR/Folder… seleccionamos el archivo hsqldb.jar que se encuentra en la carpeta hsqldb/lib que extrajimos anteriormente.

Antes de poder conectarnos ala servidor primero debemos iniciar el driver y tener a mano la url de conexión, el nombre de usuario y contraseña.

public class ProductDaoImpl implements ProductDao {

    static final String JDBC_DRIVER = "org.hsqldb.jdbc.JDBCDriver";
    static final String DB_URL = "jdbc:hsqldb:hsql://localhost/";
    static final String DB_USER = "SA";
    static final String DB_PASS = "";

    private void registerDriver() {
        try {
            Class.forName(JDBC_DRIVER).newInstance();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            System.err.println("ERROR: failed to load HSQLDB JDBC driver.");
            e.printStackTrace();
        }
    }

La implementación del método insert se encargara de agregar un nuevo producto a la base de datos, primero iniciamos el driver, abrimos la conexión y ejecutamos el comando SQL correspondiente a la inserción, tenemos en cuenta que no podemos duplicar el ID de producto.

@Override
public void insert(Product product) {
        Connection conn = null;
        try {
            registerDriver();
            // abrir la conexion 
            conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS);
            try (Statement stmt = conn.createStatement()) {
                // enviar el commando insert
                stmt.executeUpdate("insert into product values ("
                        + product.getId() + ",'"
                        + product.getName() + "',"
                        + product.getPrice() + ");");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
}

La siguiente implementación es del método read, el mismo nos devuelve el producto indicado por su ID, enviamos la correspondiente consulta select y el resultado lo convertimos a una instancia de la clase Product.

@Override
public Product read(Integer id) {
        Connection conn = null;
        Product product = null;

        try {
            registerDriver();
            // abrir la conexion
            conn = DriverManager.getConnection(DB_URL);
            // consulta select (selecciona el producto con ID especificado)
            try (PreparedStatement ps = conn.prepareStatement(
                    "select * from product where id = ?")) {
                // indicar el ID que buscamos
                ps.setInt(1, id);
                // ejecutar la consulta
                try (ResultSet rs = ps.executeQuery()) {
                    if (rs.next()) {
                        // obtener cada una de la columnas y mapearlas a la clase Product
                        product = new Product(id,
                                rs.getString("name"),
                                rs.getDouble("price"));
                    }
                }
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return product;
}

La implementación de método delete, encargada de eliminar un producto no será mostrada en este documento por ser bastante similar al método insert, para actualizar la información de un producto usaríamos el método update, este no está implementado, queda como práctica para el lector si lo desea.

Para finalizar vemos la clase principal, hacemos el ejercicio de insertar, obtener o eliminar un producto, podemos usar la aplicación HSQL DataBase Manager para ver los cambios en la base de datos, pero debemos tener en cuenta que nuestra aplicación inserta y elimina el producto de manera inmediata.

public class ProductManager {
    public static void main(String[] args) {
        ProductDao product = new ProductDaoImpl();
        
        // agregar nuevo producto
        product.insert(new Product(100, "Arroz", 1.50));
        
        // obtener el producto con ID = 100
        Product p = product.read(100);
        System.out.println(p);
        
        // eliminar el producto con ID = 100
        product.delete(100);
    }
}

GitHub: Patrón DAO con JDBC

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Detección de figuras geométricas

Procesamiento de imágenes en OpenCV

Conociendo la clase cv::Mat de OpenCV