Spring base de datos con JdbcTemplate

La clase JdbcTemplate en Spring Framework es la encargada de realizar el trabajo de captura de excepciones, enviar consultas a la base de datos, mapear los resultados (convertir los datos de la tabla en la correspondiente clase), cerrar las conexiones, etc., con esto logramos reducir el código y nos enfocamos únicamente en lo que realmente nos interesa.

En este curso vamos a mejorar la aplicación que desarrollamos en el tutorial Spring Acceso a datos con JDBC usaremos el mismo código salvo que mostraremos como JdbcTemplate facilita nuestro trabajo de programación.

Para comenzar a trabajar lo primero que necesitamos es un objeto JdbcTemplate al cual le debemos asociar un DataSource, usaremos el que creamos en el curso anterior, modificamos la clase ProductDaoImpl para agregar este objeto.

@Repository
public class ProductDaoImpl implements ProductDao {

    private JdbcTemplate jdbcTemplate;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

}

Usamos el autowiring para inyectar el DataSource que utilizamos para instanciar el JdbcTemplate, la siguiente modificación al código será la implementación de la interface.

@Override
public List<Product> todos() {

    String sql = "select * from product";

    return this.jdbcTemplate.query(sql, new RowMapper<Product>() {
        @Override
        public Product mapRow(ResultSet rs, int i) throws SQLException {
            Product p = new Product();
            p.setId(rs.getInt("ID"));
            p.setName(rs.getString("NAME"));
            p.setPrice(rs.getDouble("PRICE"));
            return p;
        }
    });

}

Utilizando jdbcTemplate.query ejecutamos la consulta indicada, RowMapper<T> nos permitirá mapear los datos obtenidos a través del ResulSet, por cada fila devuelta creamos un objeto Product para obtener al final una lista de los productos en la base de datos.

En la siguiente imagen vemos el código que teníamos anteriormente y la nueva versión.

spring datos con jdbctemplate

La clase JdbcTemplate puede ejecutar todo tipo de consultas, veamos las que usamos frecuentemente como: select, insert, update y delete.

Consulta select con JdbcTemplate

El primer ejemplo consultaremos la cantidad de elementos que tenemos en la tabla de datos, el método queryForObject(…) ejecuta la consulta y nos devuelve el resultado en un objeto del tipo indicado, en este ejemplo es un conteo por lo que recibiremos un Integer.

public Integer cantidad() {
    String sql = "select count(*) from product";
    return this.jdbcTemplate.queryForObject(sql, Integer.class);
}

Si deseamos buscar un producto en especifico necesitamos crear una consulta e indicarle el parámetro de búsqueda, por ejemplo, buscar un producto por si ID.

@Override
public Product buscar(Integer id) {
    String sql = "select * from product where ID = ?";
    return this.jdbcTemplate.queryForObject(sql, new ProductRowMapper(), id);
}

Esta consulta requiere que indiquemos cual es el ID que deseamos buscar, usando la sobrecarga del método queryForObject(sql, new ProductRowMapper(), id) podemos indicar primero la consulta, segundo el tipo de dato devuelto y al final los argumento de la consulta, cada símbolo “?” presente en la consulta será reemplazado por el argumento, en nuestro caso id.

Como el valor devuelto no es un tipo simple como Integer, debemos indicar como se debe retornar el resultado, anteriormente usamos una clase anónima, ahora haremos lo mismo pero con una clase que podemos reutilizar cada vez que la necesitemos, la llamaremos ProductRowMapper.

class ProductRowMapper implements RowMapper<Product> {
    @Override
    public Product mapRow(ResultSet rs, int i) throws SQLException {
        Product p = new Product();
        p.setId(rs.getInt("ID"));
        p.setName(rs.getString("NAME"));
        p.setPrice(rs.getDouble("PRICE"));
        return p;
    }
}

Cuando la consulta devuelva un conjunto de elementos lo hacemos de manera similar, al inicio del tutorial vemos como obtener una lista de todos los productos.

Consulta de actualización con JdbcTemplate

En esta categoría de consultas tenemos: insert, update y delete, estas se ejecutan con método update del JdbcTemplate, veamos ejemplos de su uso.

Insertar una nuevo elemento a la tabla, debemos tener cuidado de no agregar un ID repetido, esto producirá una excepción.

@Override
public void insertar(Product product) {
    String sql = "insert into product (ID, NAME, PRICE) values (?, ?, ?)";
    this.jdbcTemplate.update(sql,
            product.getId(),
            product.getName(),
            product.getPrice());
}

El uso es bastante simple, primero indicamos la consulta y luego cada uno de los argumentos de la misma, uno por cada símbolo “?”.

Actualizar un elemento de la tabla.

@Override
public void actualizar(Product product) {
    String sql = "update product set NAME = ?, PRICE = ? where ID = ?";
    this.jdbcTemplate.update(sql,
            product.getName(),
            product.getPrice(),
            product.getId());
}

Eliminar un elemento de la tabla de datos.

@Override
public void eliminar(Integer id) {
    String sql = "delete from product where ID = ?";
    this.jdbcTemplate.update(sql, id);
}

Si deseemos ejecutar consultas DDL, usadas para crear o modificar tablas por ejemplo, debemos utilizar el método execute("...").

Para probar todo lo que hemos hecho recordemos primero iniciar el servidor HSQLDB, nuestra aplicación queda del siguiente modo:

public static void main(String[] args) throws SQLException {

    AbstractApplicationContext ctx 
            = new AnnotationConfigApplicationContext(SpringConfiguration.class)

    ProductDao product = ctx.getBean(ProductDao.class);

    System.out.println("Cantidad de productos: " + product.cantidad());
    System.out.println("Producto con ID = 25: " + product.buscar(25));

    // crear un nuevo producto
    Product p0 = new Product(111, "Computer", 800.25);

    // insertar nuevo producto
    product.insertar(p0);

    // bucar el producto con ID = 35
    Product p1 = product.buscar(35);
    p1.setName("Server Computer");
    p1.setPrice(1001.25);

    // actualizar el producto con ID = 35
    product.actualizar(p1);

    // listar todos los productos
    product.todos().forEach(System.out::println);

    // eliminar el producto con ID = 111
    product.eliminar(p0.getId());

    ctx.close();
}

Con esto terminamos por ahora, en siguiente tutoriales seguiremos viendo el acceso a datos con Spring, el siguiente tema será la integración de Spring con el ORM Hibernate.

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Detección de rostros

Instalar OpenCV para Python en Windows