sábado, 14 de agosto de 2010

Java Con Netbeans Parte 11 - Conexion a base de datos

BASE DE DATOS CON JAVA
OBJETIVOS
  • Conocer la tecnologia JDBC
  • Crear una conexion a una base de datos
  • Crear consultas basicas y avanzadas
Siempre es importante el acceso a base de datos en una aplicación. JDBC (Java DataBase Connectivity) es la tecnología Java que permite a las aplicaciones interactuar directamente con motores de base de datos. La API JDBC es una parte integral de la plataforma Java, por lo tanto no es necesario descargar ningún paquete adicional para usarla. Al instalar el JDK se instala automaticamente esta API.
JDBC permite la ejecución de operaciones sobre bases de datos desde el lenguaje de programación 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.
Considerando que nos encontramos en una plataforma de Windows y un gestor de base de datos SQL usaremos uno de los siguientes metodos para conectarnos a la base de datos:
  • Puente JDBC - ODBC
  • Controlador de Java parcialmente nativo
  • Controlador JDBC de Java puro
  • Controlador de protocolo de Java puro
Recomiendo usar el primer metodo, pues asi no estaremos esperando que nos proporcionen el controlador, es facil de usar y libre de costos
Ahora si entremos de lleno al tema...
PASOS IMPORTANTES PARA COMENZAR
Partiendo de que este tutorial es para aprender todo lo relacionado a la conexion de base de datos con java, presuponemos que ya esta lista la base de datos en algun gestor de base de datos tales como SQL Server, Access, MySQL, POSTGREE, ORACLE, etc. 3 Pasos importantes
  1. Crear el Data Source Name (DSN) mediante ODBC.
  2. Conectarse a la base de datos
  3. Desarrollar nuestro codigo de java para la aplicacion deseada
Creacion de un DSN con ODBC
Como se conecta ODBC a nuestra aplicacion?
Nuestra aplicacion >> JDBC >> ODBC >> Base de datos
Para crear nuestro SDN hacer lo siguiente:
  • Ir a panel de control >> Abrir Herramientas Administratitvas
  • Abrir Origenes de Datos ODBC donde visualizaran la siguiente imagen:
  • Clin en Agregar... para adicionar un nuevo DSN.
  • Escoger el controlador de SQL Server, luego Finalizar
  • En la siguiente ventana colocar el nombre del origen de datos, descripcion (opcional) y Servidor... En esta ocasion local pues el servidor esta siendo ejecutado de manera local.
  • Luego sigue la manera de autentificarse a su sistema de base de datos, eso queda a criterio.
  • En la siguiente ventana escoger la base de datos, usaremos para nuestros ejemplos la base de datos pubs, y Siguiente
  • Sin cambiar los parametros por defecto, Finalizar y se vera la siguiente ventana... Clic en Probar origen de datos...
  • Y vera la siguiente ventana, esto es solo para cersiorar si la conexion a base de datos fue hecha correctamente. Luego Aceptar > Aceptar
  • Finalmente Aceptar.
  • Y listo, creada nuestra conexion podemos proceder a... Programar nuestras aplicaciones...
Como primer ejemplo programaremos una pequeña aplicacion donde haremos un test a una conexion hecha en java a la base de datos Pubs de SQL
 
Empezemos...
 
Aplicación Nº 1
 
Para este ejemplo usaremos un JFrame llamado FrmTest, un JButton que servira para activar el test, y un JTextArea donde visualizaremos los mensajes de nuestra aplicacion.
Ahora entramos al codigo del JButton donde insertaremos el siguiente codigo:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try{
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            Connection cn=DriverManager.getConnection("jdbc:odbc:dsnPubs");
            DatabaseMetaData meta=cn.getMetaData();
            txtMsg.setText("Conexion Realizada");
            txtMsg.append("\nGestor de base de datos : \t"+meta.getDatabaseProductName());
            txtMsg.append("\nVersion: \t\t"+meta.getDatabaseProductVersion());
        }
        catch(Exception ex){
            txtMsg.setText("La conexion no fue realizada");
        }
    }  
Y ahora solo ejecutamos nuestra aplicacion, y al hacer clik en el boton tendremos el siguiente resultado:

En el siguiente video pueden visualizar lo que hemos hecho hasta ahora para su mayor comprension:

CLASES BASICAS PARA JDBC
 
Connection Permite establecer la conexion a la base de datos. Clase fundamental en las aplicaciones que necesite acceder a una base de datos
Statement Almacena y ejecuta una instruccion SQL (T-SQL) tales como SELECT, INSERT, UPDATE y DELETE.
ResultSet Guarda los resultados de la sentencia SQL del Statement
ResultSetMetaData Guarda informacion META de los resultados. Ejemplo: Numero de columnas, Tipo de datos que guardan, cuantas filas, Nombres de Columnas, etc.
Aplicaremos estas clases en nuestra siguiente aplicación para ver en detalle como funcionan.
Aplicacion Nº 2
En esta aplicacion crearemos un formulario (JFrame) para realizar una consulta mediante un boton y que mostrará el resultado de la consulta en una area de texto. Elementos a utilizar:
JButton Nombre : btnConsulta Texto : Mostrar Consulta
JTextArea Nombre : txtMsg
 
Ahora entramos a programar el boton btnConsulta ya que este activara nuestro formulario:
private void btnConsultaActionPerformed(java.awt.event.ActionEvent evt) {                                            
        try{
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
            Connection cn= DriverManager.getConnection("jdbc:odbc:dsnPubs");
            Statement st=cn.createStatement();
            ResultSet rs=st.executeQuery("Select au_fname as Nombre, phone as Telefono, address as Direccion From authors");
            mostrarDatos(rs);
            cn.close();
        }
        catch (Exception ex){
            txtMsg.setText("Error en la conexion");
        }
    } 
Explicacion:
  • La variable cn declarada como connection almacena nuestra conexion a nuestra base de datos, especificamente dsnPubs.
  • La variable rs es un objeto de la c,lase ResultSet que almacena el resultado de nuestra consulta (query) que en este caso es "Select au_fname ...From authors"
  • Ahora para enviar los comandos a nuestra base de datos SQL necesitamos un Statement, que aqui es la variable st.
  • Luego de habernos conectado a la base de datos (Connection), crear una consulta (ResultSet) y ejecutarla (Statement), debemos mostrarla en nuestra area de texto (txtMsg), para ello hemos creado un metodo personalizado: mostrarDatos() al que le enviamos los resultados de nuestra consulta almacenados en la variable rs.
  • Luego de haber creado nuestro metodo mostrarDatos() Debemos programarlo de la siguiente manera:
private void mostrarDatos(ResultSet rs) throws Exception{
        ResultSetMetaData rmeta=rs.getMetaData();
        int nColumnas = rmeta.getColumnCount();
        txtMsg.setText("");
        for(int i=1;i<=nColumnas;i++)
            txtMsg.append(rmeta.getColumnName(i)+"\t");
        txtMsg.append("\n");
        while(rs.next()){
            for(int i=1;i<=nColumnas;i++)
                txtMsg.append(rs.getString(i)+"\t");
            txtMsg.append("\n");
        }
    }
Explicacion:
  • Al metodo mostrarDatos le enviamos el valor de rs, que en nuestra aplicacion almacenaba el resultado de nuestra consulta.
  • El uso de throws Exception se debe a que se encuentra dentro del bloque try ... catch, esto hara que cuando se produzca un error, salte del bloque try donde se encuentra a su respectivo catch.
  • Tambien, hemos utilizado la clase ResultSetMetaData pues necesitamos saber cuantos columnas vamos a usar para ordenar nuestros datos.
ResultSetMetaData
  • Con esta premisa, hemos declarado nColumnas para almacenar el numero de columnas que tiene nuestra consulta. Esto se obtiene a través de:
rs.getMetaData()
  • Sabiendo el numero de columnas, pasaremos a nombrar cada cabecera. Siendo una sola linea (Obviamente siempre solo tenemos una cabecera) usaremos:
for(int i=1;i<=nColumnas;i++)
            txtMsg.append(rmeta.getColumnName(i)+"\t");
txtMsg.append("\n");
  • Finalmente para introducir cada dato debajo de nuestra cabecera usaremos:
while(rs.next()){
            for(int i=1;i<=nColumnas;i++)
                txtMsg.append(rs.getString(i)+"\t");
            txtMsg.append("\n");
        }
La sentencia
while(rs.next()
 
evalua si cada fila tiene contenido (verdadero/true) y devolvera falso si esta vacia(falso/false)
Ojo que hablamos de cada fila entera, no solamente de una celda. No confundir.
  • Usamos un for para recorrer cada fila y rellenar nuestro txtMsg, para esto cada dato de la columna se debe convertir a String (por ser Area de Texto) con la sentencia
txtMsg.append(rs.getString(i)+"\t")
 
Y eso es todo, finalmente ejecuta tu aplicación. En este segundo video veremos todo lo aprendido en este segundo ejemplo.
 


A continuacion detallaremos mas metodos de los usados en este sencillo ejemplo

Tablas de métodos de clases básicas para JDBC 


Version del Java SKD: 1.6 (Ultima version)


Clase Connection

 void clearWarnings()
          Limpia todos los warnings reportados por el objeto Connection
 void close()
          Libera la base de datos de este objeto Connection y de los recursos consumidos por JDBC
 void commit()
          Ejecuta todos los cambios hechos desde el previo commit/rollback y libera a la base de datos de actuales bloqueos por este objeto Connection
 Statement createStatement()
          Crea un objeto Statement para enviar una sentencia SQL a la base de datos.
 Statement createStatement(int resultSetType, int resultSetConcurrency)
          Crea un objeto Statement que generará objetos ResultSet con el tipo de los parametros enviados y concurrencia
 Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
          Crea un objeto Statement que generará objetos ResultSet con el tipo de los parametros enviados, concurrencia y holdhability
 boolean getAutoCommit()
          Devuelve el modo actualo de AutoCommit del objeto Connection
 String getCatalog()
          Devuelve el nombre del actual catalogo del objeto Connection
 int getHoldability()
          Devuelve el actual holdability de los objetos ResultSet creados usando este objeto Connection.
 DatabaseMetaData getMetaData()
          Devuelve un objeto DatabaseMetaData  que contiene informacion meta de la base de datos con quien este objeto Connection representa una conexion.
 int getTransactionIsolation()
          Devuelve la transaccion actual del objeto Connection del nivel Isolation.
 Map getTypeMap()
         Devuelve el objeto Map  asociado con este objeto Connection .
 SQLWarning getWarnings()
          Devuelve el primer warning reportado por la ejecucion del objeto Connection.
 boolean isClosed()
          Devuelve verdadero si este objeto Connection ha sido cerrado.
 boolean isReadOnly()
          Devuelve verdadero si este objeto Connection se encuentra en modo lectura.
 String nativeSQL(String sql)
          Convierte la sentencia SQL a la gramatica SQL del sistema nativo.
 CallableStatement prepareCall(String sql)
          Crea un objeto CallableStatement para ejecutar procedimientos almacenados de la base de datos.
 CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
          Crea un objeto CallableStatement que generara objetos ResultSet con el tipo y la concurrencia dados.
 CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
          Crea un objeto CallableStatement  que generara objetos ResultSet con el tipo y la concurrencia dados.
 PreparedStatement prepareStatement(String sql)
          Crea un objeto PreparedStatement para enviar sentencias parametrizadas SQL a la base de datos.
 PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
          Crea un objeto PreparedStatement por defecto que tiene la capacidad de autogenerar keys.
 PreparedStatement prepareStatement(String sql, int[] columnIndexes)
          Crea un objeto PreparedStatement por defecto capaz de autogenerar keys designados por el actual array.
 PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
          Crea un objeto PreparedStatement que generara objetos ResultSet con el tipo y la concurrencia dados.
 PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
          Crea un objeto PreparedStatement que generara objetos ResultSet con el tipo, concurrencia y holdability dados.
 PreparedStatement prepareStatement(String sql, String[] columnNames)
          Crea un objeto PreparedStatement por defecto capaz de devolver keys autogeneradas designadas por el actual array
 void releaseSavepoint(Savepoint savepoint)
          Retira el objeto Savepoint dado de la transaccion actual.
 void rollback()
          Regresa todos los cambios hechos en la actual transaccion y librea cualquier base de datos bloqueda por el actual objeto Connection
 void rollback(Savepoint savepoint)
          Regresa todos los cambios hechos despues del objeto Savepoint dado fue establecido.
 void setAutoCommit(boolean autoCommit)
         Establece el modo auto-commit de la conexion al estado dado.
 void setCatalog(String catalog)
         Establece el nombre del catalogo dado en orden para seleccionar un subespacio de este objeto Connection de la base de datos en la cual se va a trabajar.
 void setHoldability(int holdability)
          Cambia el holdability de los objetos ResultSet creados using this Connection object to the given holdability.
 void setReadOnly(boolean readOnly)
          Establece esta conexion a modo de solo lectura como una sugerencia para el driver para permitir optimizacion de la base de datos.
 Savepoint
setSavepoint()
          Crea un savepoint sin nombre en la transaccion actual y devuelve el nuevo objeto Savepoint que representa
 Savepoint setSavepoint(String name)
          Crea un savepoint con el nombre dado en la transaccion actual y devuelve el nuevo objeto Savepoint que representa.
 void setTransactionIsolation(int level)
          Intenta cambiar el isolation level de la transaccion para este objeto Connection al dado.
 void setTypeMap(Map map)
          Instala el objeto TypeMap dado como el tipo de mapa para este objeto Connection.

No hay comentarios:

Publicar un comentario