¿Que es el API de conexión?
Es un conjunto de interfaces relacionadas que permiten realizar una conexión de un servidor de bases de datos a una aplicación Java. Normalmente se le denomina JDBC (Java Database Connectivity).
La idea es usar un Driver que gestione el acceso a un servidor Mysql, y así abrir la conexión con la intención de ejecutar comandos en la base de datos. Este Driver puedes descargarlo desde aquí o ir al sitio original de descargas: http://www.mysql.com/downloads/
¿Como incluyo el Driver en NetBeans?
Es sencillo! Primero extraes el Driver en un lugar especifico que te parezca cómodo, por ejemplo a la ruta C:\mysqlDriver. Luego entra a Netbeans y sitúate en la barra de herramientas "Projects".
Explorador de proyectos en Netbeans
Ahora haz clic derecho en la carpeta "Libraries" y presiona la opción "Add JAR/FOLDER..." .
Añadiendo un nuevo JAR al proyecto
Ahora busca el archivo "mysql-connector-java-5.1.31-bin.jar" en la carpeta descomprimida.
Seleccionando el conector
Cuando hayas incluido el archivo, el explorador de proyectos mostrará una nueva dependencia hacia el conector. Ahora ya puedes conectar tu aplicación Java y una base de datos en Mysql.
Nueva dependencia en nuestro proyecto
¿Como instalo el Driver en Eclipse?
La instalación en este IDE es muy similar a Netbeans. Recuerda que el primer paso es extraer el archivo del conector en un lugar conveniente para ti. Ahora enfocate en la barra de herramientas llamada "Package Explorer":
Explorador de paquetes en Eclipse
Ahora agregaremos la dependencia de nuestro archivo .jar. Para ello haremos clic derecho en el proyecto y seguiremos la ruta Build Path>Add External Archives...
Añadir el arhivo JAR de conexión
Busca el archivo "mysql-connector-java-5.1.31-bin.jar" en donde extrajiste el conector y selecciónalo.
Seleccion del conector MySQL
Si todo salió bien, tendrás una nueva librería externa con el nombre de nuestro conector. Con eso ya podrás ejecutar acciones sobre las base de datos del servidor Mysql.
Dependencia adicional a nuestro Conector
¿Como realizo la conexión a mi base de datos?
Primero incluiremos todas las clases JDBC desde el paquete sql:
import java.sql.*;
En este paquete se encuentran las clases para registrar la conexión a nuestra base de datos, crear un comando, crear instancias para ejecutar procedimientos y mucho mas.
Luego inicializamos el Driver con el método estático Class.forName(). Este método le dice a la máquina virtual de Java que busque en tiempo real la clase en el directorio de variables (PATH,CLASSPATH, etc) .En el caso de Netbeans y Eclipse también buscará en las directivas del proyecto adicionales. try{
Class.forName("com.mysql.jdbc.Driver").newInstance( );
System.out.println("Registro exitoso");
}catch(Exception e){
System.out.println(e.toString());
}
Ahora para abrir la conexión usamos la interfaz Connection, la cual recibe la referencia del servidor de bases de datos a través del método getConnection() de la interfaz DriverManager:
Connection con = null;
...
try {
con =DriverManager.getConnection("jdbc:mysql://localhost/TuBaseDeDatos?"
+"user=TuUsuario&password=TuPass");
// Otros y operaciones sobre la base de datos...
} catch (SQLException ex) {
// Mantener el control sobre el tipo de error
System.out.println("SQLException: " + ex.getMessage());
}
El String que recibe getConnection() se refiere a al cadena de conexión para acceder a nuestra base de datos. Debemos indicar el nombre del servidor, el nombre de la base de datos, usuario y password. Hay otros parámetros adicionales, pero estos son básicamente los que permiten un acceso rápido y corriente a la base de datos. Veamos la sintaxis:jdbc:mysql://[host:puerto],[host:puerto].../[base_de_datos]
[?propiedad1][=valor1][&propiedad2][=valor2]...
Aquellas partes que se encuentran en corchetes son opcionales. Finalmente usa el método close() para cerrar la conexión de forma segura.con.close();
¿Que hago para ejecutar un comando?
Usaremos la clase Statement (sentencia, esp.) para realizar operaciones sobre nuestra base de datos. Crearemos una instancia de la clase con el método createStatement() de la clase Connection:Statement cmd = con.createStatement();
Recuerda que una consulta (SELECT) retorna en una o mas filas de una tabla. En cambio la inserción, modificación y eliminación cambian la base de datos, pero no retornan en una estructura tabular. Teniendo en cuenta esto, usaremos dos métodos distintos de la clase Statement dependiendo del tipo de comando. Si vas a implementar un comando INSERT, DELETE, UPDATE, SET, etc., usas el método executeUpdate():try{
cmd = con.createStatement();
cmd.executeUpdate("DELETE FROM HERRAMIENTA WHERE NOMBRE="Serrucho"");
...
Como ves, executeUpdate() recibe como parámetro la cadena que representa al comando. En el caso de usar SELECT, emplearemos el método executeQuery(), cuyo resultado es de tipo ResultSet. Esta clase hace parte del paquete sql que importamos, y sirve para manejar las filas retornadas de una consulta. Veamos un ejemplo:ResultSet rs = null;
Statement cmd = null;
...
try{
cmd=con.createStatement();
rs = cmd.executeQuery("SELECT NOMBRE, EDAD FROM CIUDADANO");
...
Ahora, si queremos ver en pantalla los resultados o simplemente acceder a cada fila, usaremos el método next() de la clase ResulSet. Este método nos permitirá mover un puntero de lectura a la siguiente fila del resultado en forma secuencial, hasta que se haya recorrido la tabla completa. Usaremos un while que lea todo el resultado. Veamos:while(rs.next()){
String nombre = rs.getString("NOMBRE");
int edad = rs.getInt(2);
System.out.println(nombre+"-"+edad);
}
rs.close();
El código anterior implementa los métodos getString() y getInt() de ResultSet. Ambos métodos obtienen el valor de la columna retornada, especificando el nombre de la columna o su posición. Es importante cerrar el objeto ResultSet con close() para desreferenciar el puntero que estaba recorriendo la tabla.Quisiera saber como generalizar mis comandos!
Es justamente lo que quería explicarte!, ya que hacer genérico un comando es esencial para combinarlo con los datos proporcionados por los controles Swing de Java.
Supón que un usuario va a eliminar un cliente de la base de datos a través del código. ¿Como hacer para embeber este código en el String de comando?
La respuesta esta en la clase PreparedStatement. Esta clase permite ejecutar varias veces un comando con tan solo una definición genérica. Para ello usaremos el carácter "?", el cual otorga capacidad polimorfa al parámetro incluido en el comando.
Esta es la respuesta a la pregunta inicial:PreparedStatement pCmd = con.prepareStatement("DELETE FROM CLIENTE"
+"WHERE ID = ?");
...
int valor = Integer.parseInt(jTextField1.getText());
pCmd.setInt(1,valor);
pCmd.executeUpdate();
Como ves, usamos "?" para indicar que el código del cliente será variable. Luego usamos el método setInt() para especificar que en el primer "?" vamos a poner el valor de la variable extraído del Text Field.¿Como hago con los procedimientos almacenados?
Empleamos la clase CallableStatement. Esta clase permite especificar el tipo de parámetros que tiene el procedimiento, ya sea IN, OUT o INOUT. Ademas permite gestionar los resultados en forma tabular que arroje el procedimiento, si es que los arroja, u obtener el valor de los parámetros tipo OUT. Para crear un comando ejecutable usaremos el método prepareCall() de la clase Connection, veamos:CallableStatement cmdC = con.prepareCall(ejecución_procedimiento);
Para hacer la llamada del procedimiento se deben usar llaves "{}" en la elaboración de la cadena para el comando. Recuerda que cuando vimos procedimientos en Mysql usábamos la clausula CALL para ejecutarlo. Aquí también usaremos CALL para ejecutar el comando y además añadiremos el carácter "?" para indicar el polimorfismo de los parámetros.CallableStatement cmdC = con.prepareCallable("{CALL proc_dos_parametros(?,?)}");
Por defecto los parámetros son de entrada, pero si en algún momento deseas establecer que alguno es de salida, debes registrarlo mediante el método registerOutParameter(). Veamos un ejemplo:cmdC.registerOutParameter(2,Types.INTEGER);
Este método recibe dos parámetros, el primero es la posición del parámetro y el segundo es el tipo del parámetro. El tipo lo indicamos mediante los atributos de la clase Types, la cual contiene todos los tipos de datos empleados en Mysql. En este caso en particular registramos al segundo parámetro como OUT y de tipo INTEGER.
Ahora para alimentar los parámetros de entrada volvemos a usar los métodos set. Dependiendo del tipo de dato existen las alternativas setInt(), setString(), setDate(), setFloat(), etc. Todo depende de las necesidades.¿Y como ejecuto un procedimiento almacenado?
Primero usaremos el método execute(), cuyo valor de retorno es booleano. Si retorna en true significa que el procedimiento devuelve una o mas filas, por lo que usaremos luego el método getResultSet(). Si el valor es false, entonces el procedimiento se ejecuta con el método executeUpdate() ya que solo modifica la base de datos:if(cmdC.execute()){
ResultSet rs = cmdC.getResultSet();
//Otras acciones...
}else{
System.out.println("No se retornaron resultados");
}
Igual que con los comandos normales usaremos los métodos get para obtener los resultados de los parámetros tipo OUT.System.out.println("Parametro OUT:"+cmdC.getInt(1));
Amigo, ¿puedes mostrar un ejemplo completo?
Claro que si!, fíjate en la siguiente situación:
Suponga que le ha vendido un proyecto de Software a la aseguradora ProtectYAPA para gestionar los clientes y la información sobre los seguros que se ofrecen. Usted y su equipo se dan cuenta que necesitan invocar un procedimiento almacenado en el servidor Mysql, cuya función es encontrar los clientes mayores a una edad pasada como parámetro. A través de la interfaz, el usuario final digitará el valor mediante un JTextField , que está contenido en un JFrame de reglas.
Para solucionar el anterior problema implementaremos el siguiente código:try {
con =DriverManager.getConnection("jdbc:mysql://PROTECTYAPA-SERVER/aseguradora?"
+"user=admin&password=admin");
CallableStatement cmd = con.prepareCall("{CALL sp_clientes_edad(?)}");
cmd.setString(1,jTextField1.getText());
// Ejecutamos el comando
if(cmd.execute()){
// Obtenemos la tabla retornada
ResultSet rs = cmd.getResultSet();
// Obtenemos cada fila del resultado
while(rs.next()){
addFila(new Object []{rs.getString("NOMBRE"),rs.getString("APELLIDO")});
}
}
else{
System.out.println("No se retornaron filas");
}
} catch (SQLException ex) {
// Mantener el control sobre el tipo de error
System.out.println("SQLException: " + ex.getMessage());
}
El método addFila() que invocamos es la implementación modular de la agregación de filas a un JTable. Su definición es la siguiente:public void addFila(Object fila[]){
DefaultTableModel modelo = new DefaultTableModel();
modelo = (DefaultTableModel)jTable1.getModel();
modelo.addRow(fila);
}
¿Algún ejemplo con un parámetro OUT?
Por supuesto!, miremos otro requerimiento en el Sofware de la empresa de seguros:
Se desea llamar a un procedimiento almacenado en la base de datos llamado sp_mejor_vendedor. Este procedimiento posee dos parámetros de salida que reciben el código del mejor vendedor de seguros y la cantidad acumulada de ventas que realizó en el mes.
La solución propuesta por el equipo es la siguiente:try {
con = DriverManager.getConnection("jdbc:mysql://PROTECTYAPA-SERVER/aseguradora?"
+ "user=admin&password=admin");
CallableStatement cmd = con.prepareCall("{CALL sp_mejor_vendedor(?,?)}");
// Registramos los dos parámetros de salida
cmd.registerOutParameter(1, Types.INTEGER);
cmd.registerOutParameter(2, Types.INTEGER);
// Ejecutamos el procedimiento
cmd.executeUpdate();
// Obtenemos el valor de ambos parametros
int idVendedor = cmd.getInt(1);
int monto = cmd.getInt(2);
// Imprimimos los resultados del procedimiento
System.out.println(idVendedor + "-" + monto);
} catch (SQLException ex) {
// Mantener el control sobre el tipo de error
System.out.println("SQLException: " + ex.getMessage());
}
Estos pequeños ejemplos que acabo de mostrarte han sido construidos de forma secuencial y explicativa, pero seria conveniente que uses el poder de la Programación Orientada a Objetos cuando desees conectar tu aplicación Java a Mysql. Puedes definir una clase Conexion y atribuirle métodos para ejecutar comandos que devuelvan filas, ejecutar comandos que solo modifiquen la base de datos, abrir la conexión, cambiar de base de datos, etc.
Este enfoque te permitirá generalizar tus acciones sobre la base de datos en tu aplicación, lo que otorgaría flexibilidad en el desarrollo si trabajas con un equipo.
James Revelo Urrea - Desarrollador independiente http://www.hermosaprogramacion.com