Profe Macón
Programación Avanzada
2.º BT · Tecnologías de la Información
PM
Tienda de Cómics · Unidad de persistencia · Material 01

¿Dónde quedaron nuestros productos?

Ya separamos la Vista, el Controller y el Service. Nuestra tienda funciona… hasta que cerramos la aplicación. Ahora vamos a investigar qué ocurre con los datos y por qué necesitamos que Java pueda comunicarse con una base de datos.

CET1 · ObjetosCET3 · PersistenciaJava + MySQLJDBCConexión entre sistemas
1 · Retomamos el proyecto

Antes de agregar código, recordemos lo que ya resolvimos

La aplicación de la tienda de cómics tiene una organización que no existía al comenzar el curso. No vamos a abandonarla: vamos a ampliar sus capacidades.

Producto_Vista
Presenta los datos y recoge la interacción
↓
ProductoController
Coordina lo que sucede cuando pulsamos un botón
↓
ProductoService
Trabaja con productos y comprueba reglas de negocio
↓
ArrayList<Producto>
Almacenamiento que estamos utilizando

Cuando el usuario pulsa Agregar, la Vista proporciona los datos escritos en los campos, el Controller coordina la acción y el Service comprueba las condiciones del negocio. Si todo está correcto, el nuevo Producto se incorpora a una colección.

Recordamos el objeto Producto
Producto producto = new Producto(
        101,
        "Batman: Año Uno",
        790.00,
        8
);

En nuestro modelo, el código es de tipo long, el nombre es un String, el precio es double y el stock es int.

Importante: un objeto Producto representa un producto de la tienda en nuestro programa. Su existencia en memoria no garantiza que sus datos queden guardados después de cerrar la aplicación.
2 · Aparece el problema

Hagamos una prueba muy sencilla

Imagina que ejecutamos la aplicación y agregamos los siguientes productos:

CódigoNombrePrecio ($)Stock
101Batman: Año Uno7908
102Watchmen12505
103Mafalda, tomo 165012

Los productos aparecen en nuestra JTable. Podemos seleccionarlos y trabajar con ellos. Hasta aquí, todo parece correcto.

1. Abrimos

El programa crea los componentes y la lista inicial.

2. Agregamos

La lista comienza a contener objetos Producto.

3. Cerramos y reabrimos

Los productos agregados ya no aparecen.

Pregunta de investigación: ¿desaparecieron porque la JTable dejó de mostrarlos o porque los datos ya no se conservan en la colección?
Antes de seguir, piensa qué hace realmente la JTable

La tabla presenta información al usuario. No es, por sí misma, un sistema de almacenamiento permanente. Aunque mostrara los datos perfectamente, cerrarla no conservaría los objetos que estaban únicamente en la memoria del programa.

3 · Entendemos la causa

Un ArrayList no es una base de datos

Observemos una instrucción parecida a la que utilizamos en el servicio:

Colección de productos
private ArrayList<Producto> listaProductos;

public ProductoService() {
    listaProductos = new ArrayList<Producto>();
}

La primera línea declara una variable que puede referirse a una colección de productos. En el constructor se crea el ArrayList al iniciar ese objeto ProductoService.

Mientras la aplicación se ejecuta, podemos agregar, eliminar y consultar los elementos de la lista. Pero si los datos solo están en esa colección, cuando finaliza el programa no tenemos una copia persistente para recuperarlos.

Durante la ejecución

La aplicación mantiene objetos en memoria y podemos acceder a ellos mediante la colección.

listaProductos.add(producto);
≠

En una nueva ejecución

Se crea un nuevo estado de la aplicación. No reaparece automáticamente la colección de la ejecución anterior.

new ArrayList<Producto>();

Dos palabras que necesitamos distinguir

Memoria temporal

Permite mantener y manipular objetos durante la ejecución. Por sí sola, nuestra lista no conserva datos entre ejecuciones.

Persistencia

Consiste en guardar datos para recuperarlos en otro momento, incluso después de que el programa haya terminado.

Una precisión: no se trata de conservar «vivo» el mismo objeto Java. Guardaremos sus datos y, cuando volvamos a necesitarlos, podremos construir nuevos objetos a partir de ellos.
4 · Elegimos una estrategia

¿Dónde podríamos guardar los datos?

Una posibilidad sería escribirlos en un archivo. Es una alternativa válida para ciertos problemas. Pero cuando una aplicación necesita consultar, modificar, relacionar y organizar registros de distintas entidades, una base de datos relacional ofrece herramientas específicas.

En nuestro proyecto utilizaremos MySQL, un sistema gestor de bases de datos relacionales, para conservar los productos de la tienda.

Creamos un Producto → Guardamos sus datos → Cerramos el programa → Recuperamos sus datos

Para conseguirlo, nuestra aplicación necesitará enviar y recibir información de un sistema distinto al propio programa Java.

5 · Dos sistemas distintos

Java y MySQL tienen responsabilidades diferentes

La aplicación Java

Ejecuta nuestra interfaz Swing, recibe acciones, aplica las reglas de negocio y crea objetos como Producto.

La organización que ya construimos pertenece a esta aplicación.

El servidor MySQL

Gestiona bases de datos, tablas, registros, consultas SQL, conexiones y permisos de acceso.

Puede ejecutarse en nuestra computadora o en otro equipo.

Aplicación Java ⇄ Comunicación ⇄ Servidor MySQL

¿Qué significa localhost?

Si instalamos MySQL en la misma computadora que ejecuta nuestra aplicación, podemos acceder a ese servidor mediante localhost, una dirección que representa al propio equipo.

Si MySQL está en otra máquina, necesitaremos la dirección de ese servidor y los permisos correspondientes.

Una confusión frecuente: para que Java se conecte directamente a MySQL no necesitamos un servidor web Apache. MySQL recibe las conexiones de las aplicaciones mediante su propio servicio de base de datos.

¿Qué es entonces una base de datos?

Podemos organizar los datos de nuestros productos en una tabla. Cada fila representa un registro y cada columna contiene un tipo de dato.

codigonombrepreciostock
101Batman: Año Uno790.008
102Watchmen1250.005

El servidor administra esa información; nuestra aplicación necesita una forma de solicitar operaciones sobre ella.

6 · Un mismo producto, dos representaciones

¿Qué relación existe entre un objeto y una fila?

En Java escribimos:

Producto producto = new Producto(
        101, "Batman: Año Uno", 790.00, 8
);

En una tabla podríamos almacenar los valores correspondientes a ese producto:

codigonombrepreciostock
101Batman: Año Uno790.008

No son la misma cosa. El objeto existe dentro de la aplicación Java y puede tener métodos y comportamiento. La fila contiene datos organizados y administrados por MySQL.

De Java a MySQL

Tomaremos los valores de un objeto Producto y realizaremos una operación para guardarlos como registro.

↔

De MySQL a Java

Leeremos los valores de un registro y, con ellos, podremos construir un nuevo objeto Producto.

Esta traducción entre los datos del programa y los registros almacenados será una de las responsabilidades de los componentes DAO que incorporaremos más adelante. Todavía no necesitamos programarlos.

7 · Necesitamos un mecanismo de comunicación

Aparece JDBC

Si Java y MySQL son sistemas diferentes, tenemos que disponer de una forma de pedir una conexión, enviar consultas y recibir resultados.

JDBC significa Java Database Connectivity. Es una API que Java proporciona para trabajar con sistemas de bases de datos relacionales.

Recuerda que una API reúne clases, interfaces y otros elementos que permiten utilizar funcionalidades desde nuestro código.

Conectar

Solicitar una conexión con la base de datos.

Ejecutar

Enviar instrucciones SQL al servidor.

Recuperar

Leer los resultados y trabajar con ellos desde Java.

¿JDBC es un programa que instalamos?

No exactamente. Java incluye la API JDBC, cuyos elementos principales están en el paquete java.sql.

Algunos nombres que encontraremos después
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

En esta primera lectura no vamos a utilizar todavía estas clases e interfaces. Solo necesitamos reconocer que forman parte de la API y que cada una tendrá una función concreta cuando comencemos a programar la conexión y las consultas.

Idea clave: JDBC nos ofrece una manera común de realizar operaciones desde Java, sin que tengamos que programar por nuestra cuenta los detalles del protocolo de comunicación de cada gestor.
8 · La pieza que falta

Si JDBC ya está en Java, ¿para qué necesitamos un driver?

JDBC establece una API común, pero los diferentes sistemas gestores de bases de datos necesitan implementaciones que sepan comunicarse con ellos.

El driver JDBC es una biblioteca que proporciona esa implementación para un sistema concreto.

Nuestro código Java
↓
API JDBC
Operaciones comunes
↓
Driver MySQL Connector/J
Implementación para comunicarse con MySQL
↓
Servidor MySQL

No confundamos API con driver

JDBC

Es la API que utilizamos desde Java. Define operaciones y tipos comunes para trabajar con bases de datos.

Driver MySQL

Es la biblioteca que implementa lo necesario para comunicar esas operaciones con MySQL. La incorporaremos como dependencia de Maven.

Si nuestra aplicación utilizara PostgreSQL, necesitaríamos el driver JDBC correspondiente a PostgreSQL. Aunque cambiaría el driver, gran parte de la manera de programar con JDBC seguiría siendo similar.

Para no adelantarnos: todavía no escribiremos la dependencia Maven ni la clase de conexión. Lo haremos en el material siguiente, cuando estudiemos DriverManager y Connection paso a paso.
9 · Comprobamos que comprendimos

Piensa qué está ocurriendo, no memorices definiciones

Responde y observa la devolución. Puedes volver a leer cualquier apartado.

1. Cerramos la tienda y, al abrirla otra vez, no aparecen los productos que agregamos. ¿Cuál es la explicación más adecuada?

2. ¿Qué queremos conseguir al incorporar persistencia?

3. ¿Qué componente administra las tablas y sus registros?

4. ¿Cuál es la diferencia principal entre JDBC y el driver MySQL?

5. Si la base de datos está instalada en el mismo equipo, ¿qué suele indicar localhost?

10 · Cerramos la primera lectura

Ya sabemos qué problema tenemos que resolver

La tienda no necesita que volvamos a escribir la interfaz ni que abandonemos el Controller y el Service. Necesita una forma de conservar los datos que hoy solo están en memoria.

Objetos Java → Datos persistentes → Nueva ejecución → Nuevos objetos

Micro-entrega de documentación

En tu cuaderno o documento del proyecto, registra:

Producto de esta lectura: no se solicita modificar código. La evidencia es una explicación propia del problema y un esquema de los sistemas que intervendrán.

Próximo material: vamos a solicitar nuestra primera conexión a MySQL. Allí estudiaremos DriverManager, getConnection(), la dirección JDBC, Connection y los errores que pueden ocurrir.

Material en curso
← Índice del curso