Ir al contenido
wannacode

Conectarse a la base de datos desde el código

En resumen: Un programa habla con una base de datos mediante un controlador: abre una conexión a la dirección de la base, envía la consulta, lee las filas una a una y cierra la conexión.

Problema

La página «Menos de 5 €»

El sitio web de la tienda tiene una página con los productos baratos. Ya conoces la consulta para ella:

SQLbase de datos: tienda

Pero nadie en el sitio escribe consultas en un cuadro. Cuando alguien abre la página, el servidor de la tienda ejecuta un programa. El programa envía esta consulta a la base de datos, recibe las 17 filas como valores de su propio lenguaje (una cadena, un número) y las pone en el HTML. ¿Cómo habla exactamente un programa con una base de datos?

La idea

Los cinco pasos

Es igual en todos los lenguajes:

  1. Controlador. Una biblioteca que habla el idioma de una base de datos concreta (SQLite, PostgreSQL, MySQL).
  2. Conexión. El programa dice dónde está la base de datos (su dirección) y se conecta.
  3. Consulta. El texto SQL va a la base de datos.
  4. Filas. El resultado vuelve fila por fila, y el programa lee sus columnas como valores.
  5. Cierre. La conexión se libera, incluso si ocurrió un error a medias.

Aquí está la misma consulta, con una pequeña copia de la tienda en memoria (:memory:, seis productos que setup crea al empezar):

try (Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:")) {
setup(conn);
String sql = "SELECT name, price FROM products WHERE price < 5 ORDER BY price";
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql)) {
while (rs.next()) {
System.out.printf("%s: %.2f €%n", rs.getString("name"), rs.getDouble("price"));
}
}
}
Salida
Bollo de mantequilla: 0.80 €
Pan blanco: 1.20 €
Leche fresca: 1.60 €
Mantequilla: 3.20 €

Del quinto paso se ocupa el lenguaje: try (…) en Java, using en C#, close() en Python y JavaScript. En Python with termina la transacción, no la conexión, por eso aquí close() está escrito de forma explícita.

Más precisamente, para curiosos

setup ejecuta el texto SQL que crea la tabla con los seis productos:

static void setup(Connection conn) throws SQLException {
try (Statement st = conn.createStatement()) {
st.executeUpdate("""
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price REAL NOT NULL, discount INTEGER);
INSERT INTO products VALUES
(1, 'Pan blanco', 1.20, NULL), (3, 'Bollo de mantequilla', 0.80, 10), (5, 'Leche fresca', 1.60, NULL),
(7, 'Queso blanco', 7.90, 15), (9, 'Mantequilla', 3.20, NULL), (17, 'Café en grano', 14.90, 0);
""");
}
}

Los controladores de los ejemplos: sqlite-jdbc en Java (el paquete org.xerial:sqlite-jdbc), Microsoft.Data.Sqlite en C# (NuGet), y en Python y JavaScript SQLite viene incluido (sqlite3, y node:sqlite desde Node 22). Cada ejemplo se ha ejecutado y su salida es exactamente esta.

Míralo

La dirección de la base y la contraseña

SQLite es un archivo y la dirección es la ruta hasta él. Si creaste shop.db en la lección «SQL y las bases de datos reales» (sqlite3 shop.db < shop-es.sql), cambia :memory: por la ruta y quita setup: en Java es jdbc:sqlite:shop.db, en C# Data Source=shop.db, y en Python y JavaScript simplemente "shop.db". El mismo programa mostrará los 17 productos.

Una base de datos de servidor (PostgreSQL, MySQL, SQL Server) vive en otro programa, a menudo en otra computadora. Su dirección tiene un host, un puerto, un nombre de base de datos, un usuario y una contraseña:

String url = "jdbc:postgresql://localhost:5432/shop";
String password = System.getenv("SHOP_DB_PASSWORD");
try (Connection conn = DriverManager.getConnection(url, "shop_app", password)) {
// las mismas consultas
}

La contraseña no va en el código. El código va a git, donde lo ve todo el que tiene acceso, y la contraseña del sitio real es distinta de la de tu computadora. Por eso viene de fuera: de una variable de entorno, como aquí, o del almacén de secretos del proveedor de hosting.

Estos cuatro ejemplos no se ejecutan en las comprobaciones del sitio, porque necesitan un servidor PostgreSQL. Los controladores son org.postgresql, Npgsql, psycopg y pg.

Pruébalo

La consulta para otra página

La página «Agotado» del panel de administración muestra los nombres de los productos con existencias 0, en orden alfabético. Escribe la consulta que enviará el programa.

SQLbase de datos: tienda

La idea

De la columna al valor

Cada columna llega como un valor de un tipo del lenguaje. INTEGER se convierte en int (o long), REAL en double, TEXT en String / string / str. Lo interesante es NULL. En Python es None, en JavaScript null, y en Java y C# depende de cómo lo leas:

try (Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:")) {
setup(conn);
try (Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT name, discount FROM products WHERE id IN (1, 3, 17)")) {
while (rs.next()) {
int discount = rs.getInt("discount");
String text = rs.wasNull() ? "sin descuento" : discount + "%";
System.out.println(rs.getString("name") + ": getInt devuelve " + discount + ", así que " + text);
}
}
}
Salida
Pan blanco: getInt devuelve 0, así que sin descuento
Bollo de mantequilla: getInt devuelve 10, así que 10%
Café en grano: getInt devuelve 0, así que 0%

El pan blanco no tiene descuento (NULL), mientras que el café tiene un descuento del 0 %. Son cosas distintas. En Java getInt devuelve 0 en ambos casos y solo wasNull() los distingue. En C# GetInt32 sobre un NULL se detiene con un error, así que preguntas primero con IsDBNull.

Ejercicio

Los productos nuevos

La página de inicio muestra los productos nuevos: el nombre y el precio de los productos añadidos (added_at) el 1 de junio de 2025 o después, los más nuevos primero y, si la fecha coincide, por nombre.

SQLbase de datos: tienda

Test

Ponte a prueba

1. El programa leyó una fila con un precio y la mostró. ¿Cuál de estos pasos es el que más se olvida y luego tumba el sitio?
2. ¿Dónde debe guardarse la contraseña de la base de datos de la tienda?
3. En Java la columna discount es NULL y el programa llama a rs.getInt("discount"). ¿Qué recibe?
4. La consulta es la misma en los cuatro lenguajes. ¿Qué cambia si la tienda pasa de SQLite a PostgreSQL?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·