Ya sabemos por qué necesitamos una base de datos
En el material anterior comprobamos que la lista de productos no conserva los datos cuando cerramos nuestra aplicación. MySQL podrá almacenarlos, pero antes debemos conseguir que Java se comunique con su servidor.
Java · objetos Producto · Controller · Service
Medio de comunicación
Base de datos tiendacomics
En el módulo anterior aprendimos a distinguir JDBC, la API de Java para trabajar con bases de datos, del driver, la biblioteca específica que permite comunicarse con MySQL.
¿Qué necesitamos antes de escribir el código?
Vamos a suponer que el servidor MySQL está instalado y funcionando en la misma computadora, que existe la base tiendacomics y que disponemos de un usuario con acceso. Si el servidor está en otro equipo, cambiaremos su dirección.
Un servicio MySQL en funcionamiento, accesible por red.
Una base llamada tiendacomics. Todavía no necesitamos insertar productos.
MySQL Connector/J incluido como dependencia Maven de nuestro proyecto Java.
En un proyecto Maven, agregamos dentro de <dependencies> una dependencia como esta:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.4.0</version>
</dependency>Maven descarga la biblioteca y la incorpora a las dependencias del proyecto. La versión indicada es un ejemplo compatible con Java 17; conviene utilizar la versión acordada para el entorno del curso.
java.sql mediante Maven. Ese paquete ya viene con Java. Lo que incorporamos es el driver específico de MySQL.La URL JDBC: ¿a qué base queremos conectarnos?
El programa necesita una dirección para encontrar el servidor y la base de datos. En JDBC esa dirección se expresa mediante una URL de conexión.
String url = "jdbc:mysql://localhost:3306/tiendacomics";
| Fragmento | Significado |
|---|---|
jdbc:mysql: | Indica que queremos una conexión JDBC a MySQL. |
localhost | El servidor se ejecuta en esta computadora. |
3306 | Puerto habitual del servidor MySQL. |
tiendacomics | Nombre de la base de datos a utilizar. |
La URL no contiene por sí sola todos los datos necesarios para autorizar la conexión. En nuestro primer ejemplo proporcionaremos también el nombre de usuario y la contraseña.
comics2026, ¿qué parte de la URL cambiarías? ¿Y si MySQL estuviera en otra computadora?DriverManager: la clase que solicita conexiones
Ya conocemos la dirección. Ahora necesitamos que Java obtenga una conexión utilizando el driver adecuado.
La API JDBC incluye una clase llamada DriverManager. Esta clase administra los drivers registrados y permite solicitar una conexión a partir de la URL y las credenciales.
Connection conexion =
DriverManager.getConnection(url, usuario, clave);Leamos la instrucción de derecha a izquierda
DriverManager.getConnection(...)
Llama a un método estático. No necesitamos crear un objeto DriverManager. El método intenta obtener una conexión mediante un driver que reconozca la URL.
Connection conexion
Declara una variable llamada conexion, cuyo tipo es Connection. Si todo sale bien, recibe la referencia al objeto que representa la sesión de conexión.
Los argumentos url, usuario y clave son expresiones de tipo String.
DriverManager no guarda nuestros productos ni ejecuta una sentencia INSERT. Su trabajo aquí es conseguir una conexión; las operaciones SQL vendrán después.¿Cómo sabe qué driver utilizar?
El driver de MySQL reconoce las URL que comienzan con jdbc:mysql:. Cuando la dependencia está bien incorporada, los drivers JDBC modernos suelen registrarse automáticamente; por eso normalmente no necesitamos escribir Class.forName("com.mysql.cj.jdbc.Driver"), frecuente en ejemplos antiguos.
Connection: ¿qué recibimos al conectarnos?
El método getConnection() devuelve una referencia cuyo tipo es la interfaz java.sql.Connection.
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException;
Connection representa una sesión de comunicación con la base de datos. Por medio de ella podremos preparar instrucciones SQL, controlar transacciones y realizar otras operaciones JDBC.
La conexión es…
Un objeto de Java que representa nuestra comunicación con MySQL y permite acceder a operaciones JDBC.
La conexión no es…
La propia base de datos, una tabla de productos ni una colección ArrayList.
Cuando dejamos de necesitar una conexión, debemos cerrarla correctamente para liberar recursos. El servidor MySQL puede atender varias conexiones, pero estas no son ilimitadas.
Primera prueba de conexión: un ejemplo mínimo
Vamos a reunir las instrucciones en un ejemplo pequeño. Por el momento no lo mezclaremos con ProductoService ni con los botones de la vista: solo queremos comprobar la comunicación.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class PruebaConexion {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/tiendacomics";
String usuario = "usuario_prueba";
String clave = "clave_prueba";
try {
Connection conexion =
DriverManager.getConnection(url, usuario, clave);
System.out.println("Conexión establecida");
conexion.close();
} catch (SQLException e) {
System.out.println("No fue posible conectarse");
System.out.println(e.getMessage());
}
}
}Recorramos la ejecución
- Se guardan los datos de acceso en tres variables.
- El programa llega al bloque
try. DriverManager.getConnection(...)solicita la conexión al servidor.- Si se obtiene, vemos el mensaje de éxito y llamamos a
close(). - Si JDBC lanza una
SQLException, se ejecuta el bloquecatch.
try y una de ellas fallara antes de close(), podríamos dejar recursos abiertos. En la sección siguiente lo mejoraremos.SQLException: un error distinto a los del negocio
Ya estudiamos excepciones al separar las responsabilidades entre Controller y Service. Ahora recuperamos ese aprendizaje.
Formato
El usuario escribe “abc” en el campo de precio y falla la conversión numérica.
NumberFormatException
Regla del negocio
El producto tiene un precio negativo y el servicio rechaza el valor.
Excepción de validación
Persistencia
El servidor MySQL no responde o rechaza las credenciales.
SQLException
SQLException es una excepción comprobada (*checked exception*). Si un método utiliza una operación que puede lanzarla, debe manejarla mediante un try-catch o declarar con throws SQLException que puede propagarla.
public static Connection obtenerConexion() throws SQLException {
return DriverManager.getConnection(url, usuario, clave);
}La palabra throws no provoca una excepción; declara que el método puede comunicarla a quien lo invoque. Tampoco la resuelve por sí sola.
Esto resulta útil para separar responsabilidades: una clase dedicada a obtener conexiones no necesita mostrar un JOptionPane cuando MySQL falla. Puede propagar la excepción y dejar que otra capa determine cómo informar al usuario.
try-with-resources: una manera segura de cerrar
Una conexión ocupa recursos tanto en Java como en el sistema de base de datos. Conviene liberarlos aunque alguna instrucción falle.
Java dispone de una estructura llamada try-with-resources. Permite declarar recursos en el encabezado del try y cerrarlos automáticamente cuando termina ese bloque.
try (Connection conexion =
DriverManager.getConnection(url, usuario, clave)) {
System.out.println("Conexión establecida");
} catch (SQLException e) {
System.out.println("No fue posible conectarse");
System.out.println(e.getMessage());
}¿Qué cambió?
La variable conexion aparece dentro de los paréntesis del try. Cuando termina el bloque, Java invoca el cierre del recurso, incluso si se produce un error después de obtenerlo.
No tuvimos que escribir conexion.close() de forma explícita. La interfaz Connection admite este mecanismo porque implementa AutoCloseable.
¿Dónde colocaremos esta configuración?
Imaginemos que dentro de unos días tenemos ProductoDAO, ClienteDAO y VentaDAO. Todos deberán conectarse con MySQL.
Vamos a crear, cuando pasemos a la práctica, una clase específica que proporcione conexiones. Podemos llamarla ConexionBD y ubicarla en el paquete config.
public class ConexionBD {
public static Connection obtenerConexion()
throws SQLException {
// Utilizar DriverManager con la configuración de MySQL.
}
}Su tarea será conocer los datos de conexión y entregar una Connection. No será responsable de validar precios, escuchar botones ni ejecutar todas las operaciones CRUD de productos.
Cuando estudiemos DAO, será cada DAO quien solicite conexiones para ejecutar su SQL. Así, la configuración se concentra en un lugar y las operaciones de acceso a datos se mantienen organizadas.
Comprobamos lo que comprendimos
Responde estas preguntas y lee la devolución. Puedes regresar a las explicaciones cuando lo necesites.
1. ¿Qué función cumple DriverManager en nuestro ejemplo?
2. ¿Qué representa una variable del tipo Connection?
3. ¿Qué parte de jdbc:mysql://localhost:3306/tiendacomics indica el nombre de la base?
4. ¿Qué significa throws SQLException en la cabecera de un método?
5. ¿Por qué utilizamos try-with-resources con Connection?
Documentamos y preparamos el siguiente paso
Ya conocemos las piezas que necesitamos para solicitar una conexión. Todavía no hemos guardado ningún producto: eso será parte del trabajo con instrucciones SQL y DAO.
Micro-entrega de documentación
- Explica con tus palabras la diferencia entre
DriverManageryConnection. - Descompón la URL
jdbc:mysql://localhost:3306/tiendacomicse identifica cada parte. - Escribe dos causas posibles de una
SQLExceptional conectarnos. - Explica por qué preferimos
try-with-resourcesen lugar de cerrar la conexión solamente al final del bloque. - Dibuja dónde ubicarías la futura clase
ConexionBDrespecto de los DAO.
Próximo material: desde una conexión activa, aprenderemos a preparar y ejecutar instrucciones SQL. Estudiaremos PreparedStatement, executeUpdate(), executeQuery() y ResultSet usando los productos de la tienda.

