SQL Tema 7
Conexión desde Java
Ahora llega la parte más interesante: conectar Java a SQL para juntar lo mejor de los dos mundos, la programación y las bases de datos.
Preparar la base de datos#
En primer lugar, debemos tener la base de datos creada y su tabla o tablas también creadas (por ejemplo, desde DBeaver). Desde Java insertaremos datos y haremos consultas.
Crear un proyecto de Java e instalar el driver JDBC#
Java por sí solo no puede conectarse a una base de datos: necesita un software adicional que se llama driver JDBC. Debemos crear un proyecto de Java y colocar el .jar del SQLite JDBC Driver en la carpeta lib.
Enlace de descarga: repo1.maven.org/maven2/org/xerial/sqlite-jdbc (busca la versión más reciente y descarga el .jar).
Programar la conexión#
En nuestro programa de Java debemos usar algunas instrucciones para conectarnos y para lanzar inserciones de datos y consultas. Lo primero es importar la librería de SQL:
import java.sql.*;Lo siguiente, ya dentro de nuestra clase, será guardar la ruta a la base de datos en una constante:
| Palabra | Para qué |
|---|---|
private | Para que nadie de fuera de la clase acceda a ella |
static | Para poder usarla desde distintas partes de nuestro programa |
final | Para que no podamos cambiarla por error |
private static final String URL = "jdbc:sqlite:codemaker.db";// En MySQL hay un servidor: se indica dónde está, la base de datos, el usuario y la contraseña
private static final String URL = "jdbc:mysql://localhost:3306/codemaker";
private static final String USUARIO = "alumno";
private static final String CLAVE = "contraseña";
// Y al conectar: DriverManager.getConnection(URL, USUARIO, CLAVE)Con MySQL, el .jar que va en lib es el MySQL Connector/J en lugar del de SQLite. El resto del código es igual.
Importante
El fichero de la base de datos (codemaker.db) debe estar en la carpeta raíz del proyecto de Java.
Una vez configurado lo anterior, ya podemos leer o escribir en la base de datos.
Nota
Los ejemplos usan try con recursos: la conexión se abre dentro de los paréntesis del try, y Java la cierra sola al terminar, haya error o no. Es lo mismo que se hace con los ficheros en los apuntes de Java.
Leer la base de datos:
String sqlSelect = "SELECT * FROM alumnos";
try (Connection conn = DriverManager.getConnection(URL);
PreparedStatement pstmt = conn.prepareStatement(sqlSelect)) {
ResultSet rs = pstmt.executeQuery(); // Se usa solo para SELECT
System.out.println("\n--- LISTA DE ALUMNOS ---");
// El bucle rs.next() recorre la tabla de resultados fila por fila
while (rs.next()) {
// Sacamos los datos de cada columna por su nombre
int id = rs.getInt("id_alumno");
String nombre = rs.getString("nombre");
String nivel = rs.getString("nivel");
System.out.println("ID: " + id + " | Nombre: " + nombre + " | Nivel: " + nivel);
}
} catch (SQLException e) {
System.out.println("Error en la consulta: " + e.getMessage());
}Para cada tipo de columna hay un método get:
| Tipo en SQL | Método en Java | Ejemplo |
|---|---|---|
INTEGER | getInt | int edad = rs.getInt("edad"); |
REAL | getDouble | double cuota = rs.getDouble("cuota"); |
TEXT | getString | String nombre = rs.getString("nombre"); |
Escribir en la base de datos:
String sqlInsert = "INSERT INTO alumnos (nombre, nivel) VALUES (?, ?)";
try (Connection conn = DriverManager.getConnection(URL);
PreparedStatement pstmt = conn.prepareStatement(sqlInsert)) {
// Sustituimos los ? por los datos reales
pstmt.setString(1, "Marcos");
pstmt.setString(2, "Master");
pstmt.executeUpdate(); // Se usa para INSERT, UPDATE y DELETE
System.out.println("¡Registro completado con éxito!");
} catch (SQLException e) {
System.out.println("Error al registrar: " + e.getMessage());
}Cuidado
Usa siempre los ? y los pstmt.set... para meter datos en la consulta, aunque vengan del usuario. Nunca pegues el texto que escribe el usuario directamente en el String del SQL: es la puerta de entrada de uno de los ataques más famosos, la inyección SQL.
Usos avanzados#
Para consultas más complejas, actualizaciones (UPDATE) o borrados (DELETE), puedes usar el código anterior teniendo en cuenta:
- La variable
Stringcon el SQL: cambiamos la consulta en la variable. - Los parámetros (
?): nos debemos asegurar de que el número de?coincida con lospstmt.set...que añadamos debajo. - Escritura frente a lectura: depende del tipo de SQL.
| Si tu SQL es... | Método a usar | ¿Por qué? |
|---|---|---|
SELECT | .executeQuery() | Porque quiero que la base de datos me devuelva una tabla de datos (ResultSet) |
INSERT / UPDATE / DELETE | .executeUpdate() | Porque solo quiero que la base de datos haga una acción, y me devuelve un número: cuántas filas cambiaron |
Errores frecuentes#
| Mensaje | Qué significa | Cómo se arregla |
|---|---|---|
No suitable driver found for jdbc:sqlite:codemaker.db | Java no encuentra el driver | Comprueba que el .jar está en la carpeta lib del proyecto |
no such table: alumnos | Java ha abierto otro fichero de base de datos (si no existe, SQLite crea uno vacío) | Pon codemaker.db en la carpeta raíz del proyecto, junto a src y lib |
no such column: 'id' | El nombre del getInt o getString no coincide con la columna | Usa el nombre exacto de la columna: rs.getInt("id_alumno") |
unreported exception SQLException; must be caught or declared to be thrown | La conexión se ha abierto fuera de un try con recursos | Ábrela dentro de los paréntesis del try, con su catch (SQLException e) |