JTagua

Inicio » JDBC » Introducción » Introducción a JDBC.

Introducción a JDBC.


JDBC es una API de Java que permite  ejecutar sentencias SQL. (JDBC es nombre de una marca registrada y no es un acrónimo, a pesar de todo, JDBC es a menudo interpretado como “Java DataBase Connectivity”). Consta de un conjunto de clases e interfaces escrito en lenguaje de programación Java.

Usando JDBC es fácil ejecutar sentencias SQL a cualquier base de datos relacional. Por esta razón, no es necesario escribir un programa para acceder a una base de datos tipo Access, otro programa para acceder a una base de datos tipo Oracle y así para cada tipo de base de datos. Se puede escribir un solo programa usando la API JDBC y el programa será capaz de enviar sentencias SQL a la base de datos apropiada. Además con una aplicación escrita en Java, se puede ejecutar en diferentes plataformas.

Aunque la API ODBC de Microsoft es probablemente la interface de programación para acceder a bases de datos relacionales bastante usada y ofrece la posibilidad de conectar a casi la totalidad de bases de datos, tiene en contra de la API JDBC que está escrita en C y por tanto no es portable entre distintos sistemas operativos.

En la siguiente página de Oracle puede ver todas las APIS para todas las bases de datos disponibles.

El JDBC está compuesto por dos capas:

  1. El API JDBC se encarga de comunicar con la API del administrador de controladores JDBC enviándole las sentencias SQL.
  2. Un administrador de controladores de JDBC que se comunica de forma transparente para el programador con los distintos controladores disponibles para la base de datos.

La JDBC 3.0 API comprende dos paquetes, El paquete java.sql y el paquete javax.sql. Esto obliga a mantener

Para descargar e instalar el conector J que permitirá utilizar MySQL en el IDE NetBeans pulse aquí.

Mecanismo JDBC

El funcionamiento práctico de JDBC obliga a conocer los siguientes 6 procedimientos, a saber,

  1. Establecer conexión.
  2. Crear sentencia.
  3. Ejecutar sentencia.
  4. Procesar resultados.
  5. Cerrar.

1.-Establecer la conexión.

Tiene dos operaciones básicas.

DriverManager

La clase DriverManager es la capa gestora de JDBC, trabajando entre el usuario y el controlador (driver). Se encarga de seguir el rastro de los controladores que están disponibles y establecer la conexión entre la base de datos y el controlador apropiado. La clase DriverManager mantiene una lista de clases Driver que se han registrado llamando al método DriverManager.registerDriver. Un usuario normalmente no llamará al método DriverManager.registerDriver directamente, sino que será llamado automáticamente por el controlador (driver) cuando este se carga.

El usuario lo que hace es forzar que se cargue el driver, lo cual puede hacerse de dos formas, aunque la recomendada es llamando al método Class.forName(). Esto carga la clase driver explícitamente.

Para trabajar con el Puente JDBC-ODBC:

try {
Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
} catch (ClassNotFoundException cnfe) {
System.err.println(“No ha podido encontrarse el driver de ODBC.”);
}

Para trabajar con MySQL:

try {
Class.forName(“com.mysql.jdbc.Driver”);
} catch (ClassNotFoundException cnfe) {
System.err.println(“No ha podido encontrarse el driver de MySQL”);
}

Para trabajar con postgreSQL:

try {
Class.forName(“org.postgresql.Driver”);
} catch (ClassNotFoundException cnfe) {
System.err.println(“No ha podido encontrarse el driver de postgreSQL”);
}

Para trabajar con Oracle:

try {
Class.forName(“oracle.jdbc.driver.OracleDriver”);
} catch (ClassNotFoundException cnfe) {
System.err.println(“No ha podido encontrarse el driver de Oracle”);
}

No necesitamos crear un ejemplar de un driver y registrarlo con el DriverManager porque la llamada a Class.forName lo hace automáticamente. Si hubiéramos creado nuestro propio ejemplar, creariamos un duplicado innecesario, pero no pasaría nada.

Una vez cargado el driver, es posible hacer una conexión con un controlador de base de datos.

Connection

Un objeto Connection representa una conexión a una base de datos. Una sesión con una conexión incluye las sentencias SQL que son ejecutadas y los resultados que son devueltos a través de dicha conexión. Una misma aplicación puede tener una o más conexiones con una sola base de datos o puede tener conexiones con varias bases de datos diferentes.
La forma estándar de establecer una conexión con una base de datos es llamando al método DriverManager.getConnection. Este método toma como parámetro una cadena de caracteres que contiene una URL. La clase DriverManage trata de localizar el driver que pueda conectar con la base de datos representada por esa URL.

Para trabajar con el Puente JDBC-ODBC con MsAccess (Windows XP):

import java.sql.*;

public static void conexion ( ) throws Exception {

try {

// Carga el driver

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

// Define la cadena de conexión

String sourceURL = "jdbc:odbc:DSNSistema";

// Crea el objeto connection a través de DriverManager

Connection con = DriverManager.getConnection(sourceURL);

System.out.println("La conexion establecida es: "+ con);

} catch(ClassNotFoundException cnfe) {

System.err.println(cnfe);

} catch(SQLException sqle) {

System.err.println(sqle);

};

};

Para trabajar con MySQL.

import java.sql.*;

public static void conexion ( ) throws Exception {

try {

// Carga el driver

Class.forName("com.mysql.jdbc.Driver”);

// Define la cadena de conexión

String sourceURL = "jdbc:mysql://localhost/bd_pruebas”, usuario, password";

// Crea el objeto connection a través de DriverManager

Connection con = DriverManager.getConnection(sourceURL);

System.out.println("La conexion establecida es: "+ con);

} catch(ClassNotFoundException cnfe) {

System.err.println(cnfe);

} catch(SQLException sqle) {

System.err.println(sqle);

};

};

Para trabajar con postgreSQL:

import java.sql.*;

public static void conexion ( ) throws Exception {

try {

// Carga el driver

Class.forName(“org.postgresql.Driver”);

// Define la cadena de conexión

String database = “Bd”;
String username = “admin”;
String password = “admin”;

String sourceURL = "jdbc:postgresql:”+database, username, password";

// Crea el objeto connection a través de DriverManager

Connection con = DriverManager.getConnection(sourceURL);

System.out.println("La conexion establecida es: "+ con);

} catch(ClassNotFoundException cnfe) {

System.err.println(cnfe);

} catch(SQLException sqle) {

System.err.println(sqle);

};

};

Para trabajar con Oracle XE (version 10g).

import java.sql.*;

public static void conexion ( ) throws Exception {

try {

// Carga el driver

Class.forName("oracle.jdbc.driver.OracleDriver");

// Define la cadena de conexión

String sourceURL =“jdbc:oracle:thin:@localhost:1521:orcl”, “scott”, “tiger”;

// Crea el objeto connection a través de DriverManager

Connection con = DriverManager.getConnection(sourceURL);

System.out.println("La conexion establecida es: "+ con);

} catch(ClassNotFoundException cnfe) {

System.err.println(cnfe);

} catch(SQLException sqle) {

System.err.println(sqle);

};

};

2.-Crear sentencia.

Statement

Un objeto Statement se usa para enviar sentencias SQL a una base de datos. Una vez que se ha establecido una conexión con una base de datos particular, esa conexión puede ser usada para enviar sentencias SQL. Un objeto Statement se crea con el método creatStatement de Connection como en el siguiente  código:

Statement senten = con.createStatement();

En realidad el método createStatement debe llevar dos parámetros enteros que especifican el comportamiento del objeto ResultSet u hoja de datos y que luego se analizará con detalle. La sintaxis general será

public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException

donde:

int resulSetType, puede tener un valor de ResultSet.TYPE_SCROLL_SENSITIVE o ResultSet.TYPE_SCROLL_INSENSITIVE si queremos que el ResultSet mantenga los cambios realizados en dicha hoja de datos o no respectivamente. Finalmente ResultSet.TYPE_FORWARD_ONLY que sólo permite desplazamientos del cursor del ResultSet hacia adelante (Valor por defecto).

int resulSetCurrency, puede tener un valor de ResultSet.CONCUR_UPDATABLE cuando deseamos actualizar cualquier componente de dicho objeto u hoja de datos, en caso contrario indicaremos como valor ResulSet.CONCUR_READ_ONLY (Valor por defecto).


PreparedStatement

Un objeto PreparedStatement se usa para sentencias SQL que toman uno o más parámetros como argumentos de entrada (parámetros IN). PreparedStatement tiene un grupo de métodos que fijan los valores de los parámetros IN, los cuales son enviados a la base de datos cuando se procesa la sentencia SQL.
Un objeto PreparedStatement es potencialmente más eficiente que un objeto Statement porque este ha sido precompilado y almacenado para su uso futuro.

Son muy útiles cuando una sentencia SQL se ejecuta muchas veces cambiando sólo algunos valores.

Una sentencia preparada (PreparedStatement) se crea de la misma forma que un Statement convencional:

PreparedStatement updateSales = con.prepareStatement(“UPDATE productos SET ventas = ? WHERE COD = ?”);

después de esta instrucción habría que añadir

updateSales.setInt(1,75);
updateSales.setString(2,”110001″);

para finalmente ejecutar la sentencia con

updateSales.executeUpdate();

en las que la primera instrucción fija el valor del primer parámetro (ventas=75), la segunda fija el valor del segundo parámetro (Código del producto = 110001) y la tercera ejecuta la instrucción.

3.-Ejecutar sentencia.

La sentencia SQL se ejecuta a través de los métodos executeQuery o executeUpdate dependiendo de que no exista o exista modificación de los datos respectivamente. En los dos casos. Es decir,

  1. Consulta – executeQuery() Es una operación SELECT que devuelve el resultado de una consulta encapsulado en un objeto de tipo ResultSet
  2. Actualización – executeUpdate() Es una operación INSERT, UPDATE o DELETE que realiza una modificación sobre la base de datos; su resultado es un valor entero indicando el número de tuplas afectadas por esta operación.

ResultSet resul = senten.executeQuery(“SELECT a, b, c FROM Table2”);

Ó

Int filas_afectadas = senten.executeUpdate(“UPDATE personas set nombre=’Marina’ where id=4”);

Ó

Int filas_afectadas = senten.executeUpdate(“INSERT INTO contacto (nombre, apellidos, telefono) VALUES (‘Juan’, ‘Gomez’, ‘123’”);

3.1.-Método executeUpdate

Este método se usa para ejecutar todas las sentencias SQL que impliquen la creación, modificación o borrado de una tabla (INSERT, DELETE, UPDATE y comandos DDL – CREATE, DROP, ALTER,…). Por tanto, con este método realizaremos sentencias de creación de tablas (CREATE), modificación de la estructura de tablas (ALTER), destrucción de tablas (DROP), inserción de filas (INSERT), modificación de filas (UPDATE) y destrucción de filas (DELETE).

Para ejecutar una sentencia SQL con el método executeStatement es necesario pasarle como parámetro (en forma de String) la sentencia SQL que queramos ejecutar. El objeto Statement se encargará de enviar la sentencia SQL a la base de datos para que se ejecute y de devolvernos los resultados.

Devuelve un entero con las filas afectadas.

3.2.-Método executeQuery

El método executeQuery se usa para ejecutar sobre la base de datos todas las sentencias SQL de tipo “ SELECT” .Lógicamente, las sentencias SQL que ejecutemos pueden ser todo lo complejas que queramos, no hay restricciones de ningún tipo, se puede ejecutar cualquier sentencia que sea permitida por el lenguaje SQL. Para ello, lo único que tendremos que hacer es pasarle como parámetro al método executeQuery la sentencia SQL que queremos ejecutar.
Devuelve un resultSet, una hoja de datos o conjunto de filas.

4.-Procesar resultados.

ResultSet

Un ResultSet contiene todos los registros (filas) que satisfacen las condiciones impuestas en una sentencia SQL y proporciona acceso a los datos en dichos registros a través de un conjunto de métodos get que permiten acceder a los diferentes campos o atributos (columnas) del registro actual. Un ResultSet mantiene un cursor que apunta al registro actual. El método ResultSet.next() se usa para moverse al siguiente registro del ResultSet, haciendo el siguiente registro el registro actual.

Los métodos getXXX proporcionan los medios para obtener los valores de los campos, atributos o columnas del registro actual.

Para cada registro, los valores de las columnas pueden ser obtenidos en cualquier orden, pero para la mayor portabilidad, se debe hacer de izquierda a derecha y leer el valor de la columna sólo una vez. Tanto el nombre de la columna como el número de esta puede ser usado para designar la columna de la cual se quiere obtener el valor. Si en el ejemplo anterior la columna “a” es de tipo entero, la “b” del tipo cadena de caracteres y la “c” de tipo coma flotante, la siguiente porción de código imprimiría los valores de todos los registros:

while(resul.next()){
int i = resul.getInt(“a”);
String s = resul.getString(“b”);
Float f = resul.getFloat(“c”);
System.out.println(“FILA= ” + i + ” ” + s + ” ” + f);
}

o lo que es lo mismo

while(resul.next()){
int i = resul.getInt(1);
String s = resul.getString(2);
Float f = resul.getFloat(3);
System.out.println(“FILA= ” + i + ” ” + s + ” ” + f);
}

En la tabla que sigue se muestra el método adecuado para recuperar los distintos tipos de datos,

Tipo de dato SQL Tipo de dato Java devuelto por getObject() Método get apropiado
BIGINT Long long getLong()
BINARY byte[] byte[] getBytes()
BIT Boolean long getLong()
CHAR String String getString()
DATE java.sql.Date java.sql.Date getDate()
DECIMAL java.math.BigDecimal java.math.BigDecimal getBigDecimal
DOUBLE Double double getDouble()
FLOAT Double double getDouble()
INTEGER Integer int getInt()
LONGVARBINARY byte[] InputStream getBinaryStream()
LONGVARCHAR String InputStream getAsciiStream()
InputStream getUnicodeStream()
NUMERIC java.math.BigDecimal java.math.bigDecimal getBigDecimal()
REAL Float float getFloat()
SMALLINT Integer short getShort()
TIME java.sql.Time java.sql.Time getTime()
TIMESTAMP java.sql.Timestamp java.sql.Timestamp getTimestamp()
TINYINT Integer byte getByte()
VARBINARY byte[] byte[] getBytes()
VARCHAR String String getString()
VARCHAR2 String String getString()

Métodos relacionados con el cursor de ResultSet

El conjunto de datos ResultSet y hoja de datos en el caso de que el tipo no sea ResultSet.TYPE_FORWARD_ONLY, podemos mover el cursor por el conjunto de datos con diferentes métodos:

resul.first(), moverá el cursor al principio.

resul.last(), moverá el cursor al final.

resul.beforeFirst(), moverá el cursor antes del principio.

resul.afterLast(), moverá el cursor después del final.

resul.absolute (int num), moverá el cursor al número de fila indicado en su argumento entero. Si el número es positivo, el cursor se mueve al número dado desde el principio, y así absolute(1) pone el cursor en la primera fila. Si el número es negativo, mueve el cursor al número dado desde el final, por eso llamar a absolute(-1) pone el cursor en la última fila.

resul.next() mueve el cursor a la fila siguiente.

resul.previous, mueve el cursor a la fila anterior.

Otros métodos de ResultSet.

resul.getRow() permite comprobar el número de fila donde está el cursor.

resul.isFirst, resul.isLast, resul.isBeforeFirst(), resul.isAfterLast() devuelven true si el cursor se encuentra en la posición indicada por el método, en caso contrario false.

Tratamiento de las excepciones.

La mayor parte de las operaciones que nos proporciona el API JDBC lanzarán la excepción java.sql.SQLException en caso de que se produzca algún error en el acceso a la base de datos (por ejemplo: errores en la conexión, sentencias SQL incorrectas, falta de privilegios,…). Por este motivo es necesario dar un tratamiento adecuado a estas excepciones y encerrar todo el código JDBC entre bloques try/catch.

En el código de nuestro ejemplo tratamos las excepciones mostrando un mensaje de error al usuario a través de la consola:
try{
}catch(SQLException se){

// Informamos al usuario de los errores SQL que se han producido
System.out.println(“SQL Exception: “ + se.getMessage());
se.printStackTrace(System.out);

}

5.-Cerrar.

Es necesario cerrar adecuadamente la sentencia el ResultSet y la conexión.

senten.close();

resul.close();

con.close();

Conviene recordar:

El mecanismo de funcionamiento básico JDBC,

Establecer conexión: Class.forName(“…”)  y DriverManager.getConnection

Crear sentencia: Statement senten = connexion.createStatement();

Ejecutar sentencia: executeUpdate o executeQuery.

Procesar resultados: while, resul.first(), resul.last(), resul.beforeFirst(), resul.afterLast(), resul.absolute (int num), resul.next(), resul.previous, resul.getRow().

Cerrar: sentencia.close(), resultados.close(), conexion.close();


2 comentarios

  1. andrea tachiquin dice:

    Hola, muchisimas gracias, por personas como ustedes, nosotros los que no sabemos nada tenemos aportunidad de aprender, solo espero poder aplicarlo correcament, GRACIAS

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: