Spring Acceso a datos con JDBC

El Framework Spring provee muchas tecnologías de acceso a datos, la primera de ellas que veremos en esta serie de cursos es la API llamada Java Database Connectivity (JDBC), con ella podemos tener acceso a diferentes servidores de datos, como: MySQL, PostgresSQL, SQL Server, y muchos más, Spring también soporta otras tecnologías de acceso a datos más avanzadas como la utilización de ORM como Hibernate, iBATIS, JDO, JPA, también disponemos del Framework Spring Data.

Spring no solo maneja bases de datos relacionales, también se integra fácilmente con bases de datos NoSQL como: MongoDB, Neo4j, etc.

Para iniciar primero creamos un proyecto Maven, como lo hicimos en el tutorial de inicio con Spring

Lo siguiente que haremos será modificar el archivo pom.xml, debemos agregar las bibliotecas necesarias, spring-jdbc nos brinda todo lo requerida para usar la API JDBC en Spring, además añadiremos el motor de bases de datos HSQLDB que nos permite trabajar con bases de datos locales, en modo servidor o con base de datos en memoria.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>4.3.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>2.3.3</version>
    </dependency>
</dependencies>

Veamos las dependencias de nuestro proyecto en Netbeans 8.x, podremos observar cuales son los archivos .jar que hemos agregado.

spring jdbc jar

Tip: para agregar las dependencias fácilmente en Netbeans damos clic derecho sobre Dependencies y pulsamos Add Dependency… se mostrará una ventana que nos permitirá buscar y agregar de una manera rápida las dependencias.

agregar dependencia en netbeans

Los siguiente que tenemos que hacer es descargar el HSQLDB, ya tenemos el jar necesario en el proyecto, pero lo descargamos externamente para utilizar un par de herramientas extras que vienen en el paquete descargable que nos facilitarán el trabajo con este motor de datos, una vez descargada extraemos la carpeta.

Nos vamos a la carpeta extraída y ejecutamos el archivo hsqldb/bin/runServer.bat este se encargará de iniciar HSQLDB en modo servidor y además crea una base de datos llamada test.

iniciar servidor hsqldb

Dejemos la ventana de comandos abierta, si la cerramos se detendrá el servidor HSQLDB.

Ahora deseamos agregar datos a la BD recién creada, para ello ejecutamos el archivo hsqldb/bin/runManagerSwing.bat aquí podremos conectarnos al servidor e introducir, consultar o modificar datos o la misma base de datos en si.

conectarse al servidor hsqldb

Debemos cambiar la opción Type a HSQL Database Engine Server con los demás datos en sus valores por defecto bastará para conectarnos correctamente.

Una vez estemos conectados vamos a añadir datos que nos servirán para probar nuestros tutoriales Spring JDBC, para ello ubicamos el menú Options / Insert test data, para ver las nuevas tablas creadas View / Refresh Tree

hsqldb agregar datos de prueba

Utilizamos esta herramienta para ver la estructura de las tablas, en especial PRODUCT que utilizaremos en este curso, vemos las tablas en el panel izquierdo.

Con esto tenemos preparado el servidor y los datos de prueba que utilizaremos en esta serie de cursos de acceso a datos utilizando Spring con la API JDBC.

Lo siguiente que necesitamos obviamente es conectarnos al servidor, para ello necesitamos una implementación de la interface javax.sql.DataSource para propósitos de pruebas Spring nos provee de la clase DriverManagerDataSource que implementa dicha interface.

import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

@Configuration
public class SpringConfiguration {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
        dataSource.setUrl("jdbc:hsqldb:hsql://localhost/");
        dataSource.setUsername("SA");
        dataSource.setPassword("");
        return dataSource;
    }
}

Creamos el ApplicationContext a partir de esta configuración Java, obtenemos el DataSource y probamos el estado de la conexión con el método isValid(0) que devuelve true si la conexión es correcta y no está cerrada, de lo contrario produce una excepción.

AbstractApplicationContext ctx =
      new AnnotationConfigApplicationContext(SpringConfiguration.class);

DataSource dataSource = ctx.getBean("dataSource", DataSource.class);

Connection connection = dataSource.getConnection();
System.out.println(connection.isValid(0));

ctx.close();

Recordemos que el servidor debe estar ejecutándose para poder tener acceso a la base de datos, si todo está correcto al ejecutar veremos:

spring probar jdbc

Creamos una clase Product para representar los datos de la tabla del mismo nombre, añadimos también la clase ProductDaoImpl que implementa la interface ProductDao, la estructura de nuestro proyecto se queda así.

java patron dao spring

La clase Product que representa los datos de la tabla.

public class Product {

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

    //... getter y setter ...//

    @Override
    public String toString() {
        return "Product{" + "id=" + id + ", name=" + name + ", price=" + price + '}';
    }

}

La interface ProductDao nos permite listar todos los datos de la tabla.

public interface ProductDao {
    List<Product> todos();
}

La clase ProductDaoImpl que implementa la interface.

@Repository
public class ProductDaoImpl implements ProductDao {

    private DataSource dataSource;

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

    @Override
    public List<Product> todos() {

        List<Product> products = new ArrayList<>();
        Connection conn = null;

        try {
            conn = dataSource.getConnection();
            
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("select * from product");

            while(rs.next()) {
                Product p = new Product();
                p.setId(rs.getInt("ID"));
                p.setName(rs.getString("NAME"));
                p.setPrice(rs.getDouble("PRICE"));

                products.add(p);
            }

            rs.close();
            stmt.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                }
            }
        }

        return products;
    }
}

La anotación @Repository indica que se debe crear un bean de esta clase y que el mismo trabaja en la capa de acceso a datos, para habilitar esta característica recordamos agregar a la configuración Java la anotación @ComponentScan(basePackages = "carmelo.spring.jdbc.dao") indicando en que paquete se encuentran las clases anotadas.

La anotación @Autowired también la hemos visto en tutoriales anteriores, ella inyecta automáticamente el DataSource a través del método setter.

Lo siguiente que vemos es el código JDBC utilizado para consular todos los productos de la BD, el método devuelve una lista de los mismos, no entraremos en detalles sobre la API JDBC lo que tenemos que apreciar es como trabajamos con Spring y JDBC a bajo nivel.

Si observamos este código veremos que gran cantidad del mismo es para controlar excepciones y cerrar correctamente las conexiones, si implementáramos los métodos para insertar, eliminar, actualizar, tendríamos mucho código repetido y extenso, imaginemos que manejáramos las transacciones, se complicaría mucho más.

Spring nos ayuda con JdbcTemplate, este se encargará de todo ese código repetitivo, captura excepciones, maneja transacciones, etc. y nos facilitará el acceso a los datos, pero esto lo veremos en el próximo tutorial, por ahora veamos como utilizar lo que tenemos.

AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfiguration.class);

ProductDao product = ctx.getBean(ProductDao.class);
product.todos().forEach(System.out::println);

ctx.close();

Al ejecutar veremos:

spring jdbc

Comentarios

Temas relacionados

Entradas populares de este blog

tkinter Grid

Histogramas OpenCV Python

Modelo de Iluminación Phong - Tutorial OpenGL

tkinter Canvas