Programación con JDBC

  • Introducción a JDBC
  • Interfaces y clases comunes para conexiones a bases de datos
  • Acceso a bases de datos mediante JDBC

Contenido del capítulo

I. Introducción

1. Concepto

JDBC significa Java DataBase Connectivity. Es una especificación estándar desarrollada por Sun Microsystems (ahora Oracle) que permite a las aplicaciones Java interactuar con distintos sistemas de gestión de bases de datos.

La API JDBC se encuentra en el paquete java.sql, permitiendo a los desarrolladores crear programas que accedan a diversas bases de datos mediante sentencias SQL.

JDBC no puede conectarse directamente a una base de datos, sino que requiere un controlador específico proporcionado por el fabricante de la base de datos.

Las aplicaciones desarrolladas con Java y JDBC pueden ejecutarse en múltiples plataformas y bases de datos con mínima dependencia del sistema subyacente.

2. Componentes de programación JDBC

  • Aplicación cliente: Código escrito por desarrolladores que utiliza la API JDBC para enviar consultas SQL y obtener resultados.
  • Administrador de controladores: Gestiona las conexiones entre la aplicación Java y el sistema de base de datos, seleccionando el controlador adecuado.
  • Controlador JDBC: Implementación específica proporcionada por cada proveedor de base de datos que traduce las instrucciones SQL a comandos compatibles con su sistema.

3. Flujo de comunicación desde JDBC hasta la base de datos

II. Paquete java.sql

El paquete java.sql incluye interfaces y clases fundamentales:

  • Interfaz Driver y clase DriverManager
  • Clase Connection
  • Interfaz Statement o PreparedStatement
  • Clase ResultSet

1. Interfaz Driver y clase DriverManager

Todos los controladores JDBC deben implementar la interfaz Driver. Estos son proporcionados por los fabricantes de bases de datos y deben estar incluidos en el proyecto.

La clase DriverManager se encarga de establecer conexiones y gestionar los controladores.

Métodos principales de DriverManager
Método Descripción
registerDriver(Driver driver) Registra un controlador JDBC
getConnection(String url, String user, String password) Establece conexión a una base de datos usando una URL
setLoginTimeout(int seconds) Establece tiempo máximo de espera para conexión
setLogWriter(PrintWriter out) Configura salida de logs de la base de datos

2. Clase Connection

Representa la conexión entre la aplicación Java y la base de datos. Permite ejecutar sentencias SQL y devolver resultados.

Métodos comunes de Connection
Método Descripción
createStatement() Crea un objeto Statement
prepareStatement(String sql) Crea un objeto PreparedStatement

3. Interfaz Statement

Define métodos para ejecutar operaciones en la base de datos.

Métodos de Statement
Método Descripción Ejemplo
executeUpdate() Para INSERT, UPDATE, DELETE stmt.executeUpdate(query)
executeQuery() Para SELECT stmt.executeQuery(query)
execute() Para cualquier tipo de sentencia stmt.execute()

4. PreparedStatement

Es una versión optimizada de Statement que permite usar parámetros con marcadores de posición (?).

Métodos para establecer parámetros
Método Método Método Método
setAsciiStream() setBigDecimal() setBinaryStream() setBoolean()
setByte() setBytes() setDate() setDouble()
setFloat() setInt() setLong() setNull()
setObject() setShort() setString() setTime()
setTimestamp() setUnicodeStream()

Sintaxis: setXXXX(posición, valor)

  • posición: índice del parámetro (comienza en 1)
  • valor: dato real a insertar

5. ResultSet

Representa los resultados obtenidos tras ejecutar una consulta SELECT.

  • Los registros comienzan desde el índice 1
  • Un Statement solo puede tener un ResultSet activo al mismo tiempo
  • El método next() mueve el cursor a la siguiente fila
  • Se usan métodos como getString(), getInt(), etc., para recuperar valores
Métodos comunes de ResultSet
Método Descripción
getString(int index) Obtiene valor como cadena por posición
getString(String indexName) Obtiene valor como cadena por nombre de columna
getInt(int index) Obtiene valor entero por posición
getInt(String indexName) Obtiene valor entero por nombre de columna
getFloat(int index) Obtiene valor flotante por posición
getFloat(String indexName) Obtiene valor flotante por nombre de columna

6. Mapeo de tipos de datos SQL a Java

Tipo SQL Tipo Java
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp

III. Acceso a bases de datos mediante JDBC

1. Paso 1: Cargar el controlador JDBC

En Maven, agregar dependencia:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.29</version>
</dependency>

Registrar el controlador:

Base de datos Controlador
MySQL Class.forName("com.mysql.jdbc.Driver")
Oracle Class.forName("oracle.jdbc.driver.OracleDriver")
SQL Server Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")

Nota: En versiones recientes de JDBC, el registro automático es posible, por lo tanto, Class.forName() puede omitirse.

2. Paso 2: Establecer conexión

Connection conn = DriverManager.getConnection(url, user, pwd);

URL JDBC sigue formato:

jdbc:<subprotocol>:<subname>

Ejemplo MySQL:

jdbc:mysql://localhost:3306/mydb

3. Formatos de URLs JDBC

Base de datos Controlador URL
MySQL 5.7 com.mysql.jdbc.Driver jdbc:mysql://<hostname>[:<port>]/<dbname>
MySQL 8 com.mysql.cj.jdbc.Driver jdbc:mysql://<hostname>[:<port>]/<dbname>?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai
SQL Server 2005 com.microsoft.sqlserver.jdbc.SQLServerDriver jdbc:sqlserver://[ip]:[port];DatabaseName=[Database];user=[user];password=[pw]
Oracle Thin oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@[ip]:[port]:[sid]

Parámetros específicos para MySQL

Parámetro Significado Valor típico
user Usuario de base de datos -
password Contraseña del usuario -
useSSL Usar conexión segura false
useUnicode Soporte Unicode true
characterEncoding Codificación de caracteres utf8
serverTimezone Zona horaria del servidor Asia/Shanghai
autoReconnect Reconexión automática -
zeroDateTimeBehavior Manejo de fechas cero convertToNull

Ejemplos de URL:

jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true

4. Paso 3: Crear objeto Statemant

Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.prepareStatement(sql);

5. Paso 4: Ejecutar sentencia SQL

ResultSet rs = stmt.executeQuery(sql);
ResultSet rs = pstmt.executeQuery();

6. Paso 5: Procesar resultados

while(rs.next()) {
    String col1 = rs.getString(1);
    String col2 = rs.getString(2);
    int col3 = rs.getInt(3);
}

7. Paso 6: Cerrar recursos

finally {
    try {
        if(rs != null) rs.close();
        if(stmt != null) stmt.close();
        if(conn != null) conn.close();
    } catch(SQLException e) {
        System.out.println(e.toString());
    }
}

8. Ejemplo completo

List deptList = new ArrayList();
Connection conn = null;
try {
    Class.forName("com.mysql.cj.jdbc.Driver");
    String strUrl = "jdbc:mysql://localhost:3306/hrms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";
    conn = DriverManager.getConnection(strUrl, "root", "root");
    Statement stm = conn.createStatement();
    String strSql = "select * from Dept";
    ResultSet rs = stm.executeQuery(strSql);
    while(rs.next()) {
        Dep clsDep = new Dep();
        clsDep.setDepId(rs.getString(1));
        clsDep.setDepName(rs.getString(2));
        clsDep.setDepDesc(rs.getString(3));
        deptList.add(clsDep);
    }
} finally {
    conn.close();
}

Diferencias entre Statement y PreparedStatement

Creación
Statement statement = conn.createStatement();
PreparedStatement preStatement = conn.prepareStatement(sql);
Ejecución
ResultSet rSet = statement.executeQuery(sql);
ResultSet pSet = preStatement.executeQuery();
Comparativa
  • Rendimiento: PreparedStatement precompila la sentencia y permite reutilizarla con diferentes parámetros, mientras que Statement compila cada vez.
  • Seguridad: PreparedStatement evita inyecciones SQL al separar código y datos.

Etiquetas: JDBC MySQL Oracle SQLServer java

Publicado el 8-16 07:53