Java y su Jdbc Introduccin Generalmente los programas trabajan grabando y/o consultado datos de medios de almacenamiento. Para responder a esta necesidad en nuestros programas Java, vamos a utilizar herramientas de servicios de bases de datos como MySql o Postgres instaladas sobre servidores, intranet o bien internet. Nuestro objetivo es que el lector comprenda el manejo de la interfaz Jdbc de Java, y su interaccin con los servicios de bases de datos desde proyectos Java desarrollados en el IDE Netbeans. Siempre provocando su enriquecimiento en el manejo de los objetos intervinientes y sobre la programacin orientada a objetos. Servicios de bases de datos Como base debemos tener acceso a un servicio de base de datos, el cual lo podremos lograr instalando el servicio en nuestro computador o bien un administrador de alguna red Lan o Wan nos debe permitir acceder a dicho servicio. Para que el servicio funcione en nuestro computador, podemos bajar de la nube el software adecuado e instalarlo. Nosotros en este texto nos inclinaremos a que ustedes trabajen con el software wampserver que posee el servicio de bases de datos MySql. De modo que podemos instalar el paquete WampServer (Servidor Windows, Apache, MySql y Php) que nos da la posibilidad de poseer un servidor local (localhost). Dicho software lo podemos bajar de www.wampserver.com . Si tenemos como SO Linux, debemos bajar e instalar el LampServer. Al ser instalado el software en sus computadores ustedes observaran que el servicio estar disponible a partir de la URL o direccin localhost que en general trabaja por el puerto de comunicacin 3306 para MySql. Les recomendamos establecer el usuario root y la clave de acceso (en blanco). El servicio MySql debe estar activo para poder trabajar con l. Y lo activaremos a partir del ejecutable instalado con el software start wampserver. Observaremos el la barra de herramientas el icono presentado. Si vamos a trabajar con MySql residente en un servidor de alguna red, el administrador nos debe de proveer de la URL, el nombre de la Base de Datos, nombre de usuario y clave de acceso. Desde luego, debemos tener conectividad. WampServer como localhost A partir del icono de la barra de herramientas, tendremos acceso a algunas funcionalidades de wampserver. Frente a nuestros objetivos, esto no es importante ya que pretendemos desarrollar todas nuestras tareas desde Netbeans, de todos modos puntualizaremos algunas. Desde el men de wampserver se puede: -
Poner On u Off line al wampserver
Poner On u Off servicios por separado Configurar servicios
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte -
Acceder al localhost Ejecutar phpAmin Acceder a la consola de MySql
Disposicin y creacin de una base de datos desde Netbeans
Disponer de una base de datos y tener acceso a ella es bsico para comenzar a trabajar con el servicio MySql. De modo que la tenemos que crear y hay varias alternativas para hacerlo: -
A partir del phpAmin de wampServer
A partir de la consola de MySql O bien desde Netbeans
Nos avocaremos a trabajar desde Netbeans. La
solapa de Servicios de Netbeans, desde la opcin Databases, nos brinda la posibilidad de trabajar con los servicios de bases de datos instalados en cualquier URL al cual tengamos acceso. Al poner en ejecucin Netbeans, el IDE detecta el servicio MySql en nuestro localhost y solo debemos registrarlo en el servicio de Databases a partir de la opcin del men desplegado al tocar botn derecho sobre databases, y seleccionando Register MySQL Server
Luego estando conectados podremos crear una
base de datos a partir de la opcin Create Database, donde podemos indicar como nombre paradigmas. Esto provoca que en el servicio Databases nos aparezca una nueva conexin a partir de la cual podremos trabajar con la base de datos creada (paradigmas).
Ahora tenemos como servicio de Netbeans la
conexin a la base de datos MySql paradigmas sobre el localhost. Esto significa que podemos trabajar con ella, por ejemplo creando tablas, de todos modos esto, seria adecuado realizarlo desde programas Java. Si instalamos el servicio de bases de datos Postgres tendramos que haber trabajado de igual modo solo que por el Port 5432.
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte
Interfaz API Jdbc de Java
Java Database Connectivity, ms conocida por sus siglas JDBC, es una API (interfaz de programacin de aplicaciones) que permite la ejecucin de operaciones sobre bases de datos desde el lenguaje de programacin Java, independientemente del sistema operativo donde se ejecute o de la base de datos a la cual se accede, utilizando el dialecto SQL del modelo de base de datos que se utilice. El API JDBC se presenta como una coleccin de interfaces Java y mtodos de gestin de manejadores de conexin hacia cada modelo especfico de base de datos. Un manejador de conexiones hacia un modelo de base de datos en particular es un conjunto de clases que implementan las interfaces Java y que utilizan los mtodos de registro para declarar los tipos de localizadores a base de datos (URL) que pueden manejar. Para utilizar una base de datos particular, el usuario ejecuta su programa junto con la biblioteca de conexin apropiada al modelo de su base de datos, y accede a ella estableciendo una conexin, para ello provee el localizador a la base de datos y los parmetros de conexin especficos. A partir de all puede realizar con cualquier tipo de tareas con la base de datos a las que tenga permiso: consulta, actualizacin, creacin, modificacin y borrado de tablas, ejecucin de procedimientos almacenados en la base de datos, etc. Elementos de conexin con gestores de bases de datos desde Java Al presentarse la necesidad de desarrollar un programa Java que establezca la conexin con algn servicio de bases de datos, debemos tener claro que el servicio puede poseer varias bases de datos y nosotros vamos a establecer una conexin por cada base de datos que necesitamos trabajar. Es importante destacar que las bases de datos se pueden encontrar en servidores distintos y adems administradas por servicios Sql diferentes. Libreras necesarias en nuestros proyectos En nuestro proyecto de aplicacin Java, sobre la plataforma del IDE Netbeans, tenemos que aadir las bibliotecas, drivers o interfaces adecuadas para el servicio Jdbc que utilizaremos. De modo de disponer de las herramientas adecuadas para trabajar con los gestores de bases de datos con las que pretendemos conectar. MYSQL JDBC Driver es la biblioteca adecuada para MySql y PostgreSQL JDBC Driver es la de Postgres. Disposicin del driver ejecutable del servicio Jdbc Nuestro cdigo Java, antes que nada, debe explicitar la bsqueda y carga del runtime o ejecutable ubicado en la librera aadida al proyecto. Esto lo podemos lograr a partir del mtodo forName() que retorna la clase del objeto asociado. Por ejemplo: Class.forName(com.mysql.jdbc.Driver) chequea la existencia de la clase Driver en la librera MYSQL JDBC Driver, para el servicio Jdbc y el subservicio Mysql. Si la encuentra la pone a disposicin a partir de su ejecutable, caso contrario se produce una excepcin de tipo classNotFoundException(). Completemos: public class Main {
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte
public static void main(String[] args) throws ClassNotFoundException {
try { Class.forName("com.mysql.jdbc.Driver"); System.err.println("Cargo el Driver MySQL."); } catch (ClassNotFoundException ex) { System.err.println("No encuentra Clase Driver MySql."); System.err.println(ex.getMessage()); } } } Si no aadimos la librera MYSQL JDBC Driver a nuestro proyecto, se producir la excepcin de ClassNotFoundException ejecutndose el catch. Si carga el driver todo estar ok y podremos continuar tratando de conectar y usar el servicio de bases de datos. El administrador de drivers Jdbc DriveManager es la clase que brinda el servicio bsico para la gestin del conjunto de drivers Jdbc. La encontramos como extensin de Object de java.lang.object en java.sql.DriveManager. Por lo que en nuestro programa .java donde pretendemos utilizarla debemos indicar import java.sql.DriverManager; para disponer de ella. La funcionalidad getConnection() de la clase DriveManager es la encargada de intentar la conexin, que en caso afirmativo entrega un objeto de la clase Connection, y en caso contrario se produce una excepcin de tipo SQLException(). Para disponer de la clase Connection debemos indicar el import java.sql.Connection; DriveManager.getConnection() posee los siguientes parmetros al intentar establecer la conexin con la base de datos: URL: donde se especifica: jdbc:subprotocolo:subnombre : intentara establecer la conexin con la base de datos indicada y seleccionar el drive adecuado de su lista registrada de Jdbc drivers. Ejemplo: jdbc:mysql://localhost/paradigmas Con protocolo Jdbc, subprotocolo MySql abrir del host local la base de datos denominada paradigmas. user: indica el usuario de la base de datos. password: indica la clave del usuario de la base de datos. Ejemplo: DriverManager.getConnection("jdbc:mysql://localhost/paradigmas","root",""); Completemos: import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Main { public static void main(String[] args) throws ClassNotFoundException, SQLException {
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte try { Class.forName("com.mysql.jdbc.Driver"); System.err.println("Cargo el Driver MySQL."); String url = "jdbc:mysql://localhost/paradigmas"; Connection con = DriverManager.getConnection(url,"root",""); System.err.println("Conectado con DB paradigmas"); con.close(); System.err.println("Desconectado con DB paradigmas"); } catch (ClassNotFoundException ex) { System.err.println("No encuentra el Driver MySql."); System.err.println(ex.getMessage()); } catch (SQLException ex) { System.err.println("No puede conectar con DB paradigmas."); System.err.println(ex.getMessage()); } } } Si Connection con = DriverManager.getConnection(url,"root",""); falla, se ejecuta el catch del SQLException, y esto puede ocurrir por las siguientes razones: - Estar fuera de servicio el MySql en el servidor. - Haber indicado mal la Uro alguno de sus componentes. - No existir la base de datos paradigmas. - Haber indicado mal el usuario y/o su clave. si tiene xito, quiere decir que estamos conectados con la base de datos paradigmas y estamos en situacin de poder trabajar con ella. El mtodo close() del objeto con (tipo Connection) establece que se cierre la conexin. Declaraciones o sentencias Sql Las sentencias o declaraciones Sql nos permitirn explicitar el tipo de tarea que necesitamos desarrollar con la base de datos que estamos conectados. La clase Statement (sentencia) nos permite crear los objetos del tipo adecuado para especificar directivas Sql sobre nuestra conexin. Debemos hace el import de com.mysql.jdbc.Statement para disponer de objetos de esta clase. Statement sentencia = NULL; define el objeto sentencia y lo inicializa como nulo. Statement sentencia = (Statement) con.createStatement(); define el objeto sentencia y lo inicializa hacia la conexin con. Para esto se debe indicar el cast (Statement). Podemos ahora ejecutar una sentencia Sql indicando una directiva. El mtodo executeUpdate(directiva) nos proporciona esta posibilidad. Ejemplo: Statement sentencia = (Statement) con.createStatement(); String directiva = "CREATE TABLE producto (codigo INT, nombre VARCHAR(45), precio REAL)"; sentencia.executeUpdate(directiva);
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte Estas lneas pretenden crear la tabla producto sobre la base de datos a la cual esta conectado el objeto con. Completemos: import com.mysql.jdbc.Statement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Main { public static void main(String[] args) throws ClassNotFoundException, SQLException { try { Class.forName("com.mysql.jdbc.Driver"); System.err.println("Cargo el Driver MySQL."); String url = "jdbc:mysql://localhost/paradigmas"; Connection con = DriverManager.getConnection(url, "root", ""); System.err.println("Conectado con DB paradigmas"); Statement sentencia = (Statement) con.createStatement(); String directiva = "CREATE TABLE producto (codigo INT, nombre VARCHAR(45), precio REAL)"; try { sentencia.executeUpdate(directiva); System.err.println("Creada la tabla producto."); } catch (SQLException ex) { System.err.println("No pudo crear la tabla producto."); System.err.println(ex.getMessage()); } sentencia.close(); con.close(); System.err.println("Desconectado con DB paradigmas"); } catch (ClassNotFoundException ex) { System.err.println("No encuentra el Driver MySql."); System.err.println(ex.getMessage()); } catch (SQLException ex) { System.err.println("No puede conectar con DB paradigmas."); System.err.println(ex.getMessage()); } } } Observamos que sentencia.executeUpdate(directiva); debe ser envuelto por un try{} catch(SQLException){}, ya que puede suceder que la tabla exista en la base de datos con anterioridad a su ejecucin. Las directivas Sql que veremos son:
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte -
Create Table: para crear tablas.
Insert: para insertar registros o filas en una tabla. Delete: para borrar registros o filas de una tabla. Update: para modificar registros o filas de una tabla. Select: para seleccionar registros o filas de una tabla.
<objeto Statement>.executeUpdate(directiva) nos resolver las directivas Create, Inset, Delete y
Update. Y <objeto Statement>.executeQuery(directiva) trabaja con la directiva Select. Almacenando resultados de consultas La directiva Select nos permite a partir de una sentencia Sql ejecutada sobre una conexin, obtener algn resultado. Dicho resultado lo podemos almacenar en un objeto de tipo ResultSet. El mtodo executeQuery() de la clase Statement nos inicializar un objeto ResultSet. ResultSet resultado = (ResultSet) sentencia.executeQuery(directiva); resultado ser en definitiva una matriz que contenga tantas columnas como tenga la tabla consultada y filas como las que se obtengan de acuerdo a las condiciones impuestas y registros de la tabla respondan a la condicin. Una estructura repetitiva nos permite recorrer la matriz de resultado ResutSet. Completemos: import com.mysql.jdbc.ResultSet; import com.mysql.jdbc.Statement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class Main { public static void main(String[] args) throws ClassNotFoundException, SQLException { try { Class.forName("com.mysql.jdbc.Driver"); System.err.println("Cargo el Driver MySQL."); String url = "jdbc:mysql://localhost/paradigmas"; Connection con = DriverManager.getConnection(url, "root", ""); System.err.println("Conectado con DB paradigmas"); Statement sentencia = (Statement) con.createStatement(); String directiva = "SELECT * FROM productos"; try { ResultSet resultado = (ResultSet) sentencia.executeQuery(directiva); System.err.println("Consulta realizada."); while(resultado.next()){ System.out.printf("Cdigo: %d Nombre: %s\n",Integer.valueOf(resultado.getString("codigo")),resultado.getString("descripcion")); } } catch (SQLException ex) {
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte System.err.println("No pudo realizar la consulta en la tabla productos."); System.err.println(ex.getMessage()); } sentencia.close(); con.close(); System.err.println("Desconectado con DB paradigmas"); } catch (ClassNotFoundException ex) { System.err.println("No encuentra el Driver MySql."); System.err.println(ex.getMessage()); } catch (SQLException ex) { System.err.println("No puede conectar con DB paradigmas."); System.err.println(ex.getMessage()); } } } Referencias: http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136101.html Clase que nos gestione la conexin en nuestros proyectos Ya que nuestros proyectos necesitarn trabajar con conexiones a bases de datos, en diferentes puntos de los mismos, es apropiado pensar que disponiendo de una clase que nos gestione las conexiones encontraremos simplicidad y organizacin en el manejo de objetos que interacten con las bases de datos. Estructura de la clase GestionConexion Esta clase debe tener la facultad de permitirnos identificar y administrar los objetos GestionConexion. De modo tal de detallar sus propiedades sobre el servicio utilizado, la direccin de la base de datos, si tiene conexin y sentencias. Y adems las funcionalidades que nos permitan conectar, desconectar y averiguar sobre la carga del driver. Sus propiedades pueden ser: Connection connection (composicin) Statement statement (composicin) String driver String protocolo String servidor String database String usuario String clave Sus funcionalidades pueden ser: Asesores y mutadores de propiedades. Constructores polimrficos en cuanto a las propiedades GestionConexion() (por default a MySql) GestionConexion(driver, protocolo, servidor, database, usuario, clave) Mtodo que chequea y carga el driver
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte Mtodo que conecta Mtodo que cierra la conexin Destacamos que para las propiedades de tipo Connection y Statement debemos importar dichas interfaces desde la bilioteca java.sql. Tambin debemos importar las clases SQLExcepcion y DriveManager de la bilioteca java.sql ya que pretendemos salvar los errores de comandos Sql y obtener conexiones a partir de DriveManager. Cdigo de la clase GestionConexion import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import javax.swing.JOptionPane; public class GestionConexion { private Connection connection; private Statement statement; private String driver; private String protocolo; private String servidor; private String database; private String user; private String password; public GestionConexion() { System.out.println("Constructor Conexion por defecto a MySql."); this.driver = "com.mysql.jdbc.Driver"; this.protocolo = "jdbc:mysql"; this.servidor = "localhost"; this.database = "paradigmas"; this.user = "root"; this.password = ""; } public GestionConexion(String dbms, String servidor, String database, String user, String password) { if (dbms.toUpperCase().equals("MYSQL")) { this.driver = "com.mysql.jdbc.Driver"; this.protocolo = "jdbc:mysql"; } else if (dbms.toUpperCase().equals("POSTGRES")) { this.driver = "org.postgresql.Driver"; this.protocolo = "jdbc:postgresql"; } this.servidor = servidor; this.database = database; this.user = user;
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte this.password = password; } public String getDriver() { return driver; } public void setDriver(String driver) { this.driver = driver; } public String getProtocolo() { return protocolo; } public void setProtocolo(String protocolo) { this.protocolo = protocolo; } public Connection getConnection() { return connection; } // end getConection() public void setStatement(Statement statement) { this.statement = statement; } public Statement getStatement() { return statement; } public String getDatabase() { return database; } // end getDatabase() public void setDatabase(String database) { this.database = database; }//end setDatabase(); public void setConnection(Connection connection) { this.connection = connection; } // end setConnection() public String getServidor() { return servidor; } // end getServidor() public String getUser() { return user; } // end getUser()
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte
public String getPassword() {
return password; } // end getPassword() public boolean isDriver() { try { Class.forName(getDriver()); } catch (ClassNotFoundException ex) { return false; } return true; } public void conectar() throws SQLException, ClassNotFoundException { System.out.println("Conectando ..."); if (isDriver()) { String url = getProtocolo() + "://" + getServidor() + "/" + getDatabase(); try { setConnection(DriverManager.getConnection(url, getUser(), getPassword())); setStatement(getConnection().createStatement()); } catch (SQLException ex) { System.err.println("No puede conectar a la Base de Datos."); System.err.println(ex.getMessage()); JOptionPane.showMessageDialog(null, "Error en Coneccin...", "ADVERTENCIA", JOptionPane.ERROR_MESSAGE); throw (ex); } } else { System.err.println("No encuentra el Driver."); JOptionPane.showMessageDialog(null, "Error Driver Base de Datos...", "ADVERTENCIA", JOptionPane.ERROR_MESSAGE); System.exit(0); } } public void cerrar() { try { connection.close(); } catch (SQLException ex) { System.err.println("No puede cerrar conexion a la Base de Datos."); System.err.println(ex.getMessage()); JOptionPane.showMessageDialog(null, "Error Cerrar BD...", "ADVERTENCIA", JOptionPane.ERROR_MESSAGE); } } }
Paradigmas de programacin FRT UTN 2012
Ing. Ubaldo Bonaparte Actualizaciones de registros de tablas. Actualizar una tabla, significa dar de alta, modificar y borrar registros de la misma. Esto nos hace pensar que por algunos campos, los registros se deben diferenciar. De otro modo, sera un inconveniente encontrar un registro para borrarlo o modificarlo. O bien si queremos grabar un nuevo registro es necesario que no haya sido grabado con anterioridad, o sea que no exista en la tabla. Generalmente las actualizaciones responden a esta lgca. De todos modos hay que tener cuidado ya que pueden existir lgicas de otro tipo segn la naturaleza de los datos almacenados. ABM de productos Supongamos tener como cliente un negocio que vende productos. Dichos productos estn involucrados en muchos procesos, tal como las compras a proveedores, la administracin del stock y las ventas a clientes. De modo que es de pensar que tendremos la tabla Productos en la base de datos del negocio de nuestro cliente y un proceso importante sera el encargado de actualizar la tabla. La tabla Productos puede poseer la siguiente estructura de registros: Integer cdigo // cdigo nico del producto Varchar descripcin // denominacin del producto Float precioDeVenta // cuanto debe pagar un cliente al comprarlo Integer stock // cantidad de existencias del producto Pensando en la identificacin de productos por cdigo de barra o por una codificacin interna de nuestro cliente, diramos que cdigo, es el campo que no se repite o bien el campo clave de la tabla. De este modo cdigo es el elemento que enmarca la lgica destacada en prrafo anterior. Vamos a disear un programa que a partir de una interfaz visual del usuario, permita realizar las tres operaciones bsicas para actualizar la tabla (altas, bajas y modificaciones) y algunas operaciones tiles para el usuario como ver todos los productos, buscar un producto, ver el siguiente, ver el anterior, etc. Lgica para las operaciones bsicas: - Si no existe cdigo en la tabla, podemos dar el alta del producto - Si existe cdigo en la tabla, podemos borrar el producto - Si existe cdigo en la tabla, podemos modificar los datos del producto De modo que cdigo ser el elemento de bsqueda en la tabla. Vamos a disear la interfaz visual del usuario.