lunes, 28 de mayo de 2012

JDBC: Conexión con Base de Datos

¿Que es JDBC?
      JDBC es el acrónimo de Java Database Connectivity, una API  que 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 lenguaje SQL del móldelo de base de datos que se utilice.
      Esta conformada por diversas clases e interfaces ubicadas en el paquete java.sql.

La necesidad de una librería
      Al trabajar con JDBC resulta necesario agregar un jar al proyecto que contiene las clases necesarias que se utilizan para “dialogar” con un DBMS. Cada DBMS tiene su propio archivo jar. Estos archivos se pueden obtener de:

      -http://developers.sun.com/product/jdbc/drivers

También es posible conseguir estos archivos jar en la página web correspondiente a cada DBMS, por ejemplo, en caso de usar DMBS Oracle es posible buscarlo en la página de Oracle: www.oracle.com. En nuestro caso vamos a usar el jar de MySQL, el MySQL connector y lo podemos descargar desde acá:


Dentro del zip que se descarga se encuentra el jar.

Conexión con la base de datos

-La interfaz Connection
      Para poder trabajar con una base de datos, el punto de partida siempre es conseguir una conexión, es decir un objeto de tipo Connection (este objeto pertenece a una clase que implementa la interfaz Connection).


-Construccion de un Administrador de Conexiones
      Para poder obtener una conexión, una forma simple y comoda de trabajar es armar una clase llamada, por ejemplo, AdministradorDeConexiones, que contenga dentro de un método (obtenerConexion()) el código necesario para obtenerla.
      A continuación se presenta un ejemplo de la clase con su correspondiente método:


package ar.com.et3.lab8.ejercicio1.administrador;
import java.sql.Connection;
import java.sql.DriverManager;
/**
* @author Martin
 */
public abstract class AdministradorDeConexiones {   
    public AdministradorDeConexiones() {
    }
    public static Connection getConnection() throws Exception
    {
        // Establece el nombre del driver a utilizar
        String dbDriver = "com.mysql.jdbc.Driver";       
        // Establece la conexion a utilizar contra la base de datos
        String dbConnString = "jdbc:mysql://localhost/6to_ET3";       
        // Establece el usuario de la base de datos
        String dbUser = "root";       
        // Establece la contraseña de la base de datos
        String dbPassword = "";       
        // Establece el driver de conexión
        Class.forName(dbDriver).newInstance();       
        // Retorna la conexión
        return DriverManager.getConnection(dbConnString, dbUser, dbPassword);
    }        
}

Como consultar datos


El metodo createStatement()

      El método createStatement() se utiliza para crear un objeto que modela a una sentencia SQL. Es un objeto del tipo de una clase que implementa la interfaz Statement, y provee la infraestructura para ejecutar sentencias SQL sobre una conexión con una base de datos.
      La forma de construir un objeto de este tipo es:
     
      Statement stmtConsulta = laconexion.createStatement();

El método executeQuery()
      El método executeQuery() se utiliza para ejecutar una sentencia SQL y obtener el resultado correspondiente dentro de un objeto del tipo ResulSet. Este objeto representa un conjunto de resultados que se obtienen como consecuencia de ejecutar la sentencia SQL del tipo SELECT a través de la conexión.
      La forma de generar un objeto de este tipo es:
     
      ResulSet rs = stmConsulta.executeQuery(laConsulta);

Como realizar una consulta
     
         // Define la conexión
        Connection laConexion = AdministradorDeConexiones.getConnection();       
        // Arma la consulta y la ejecuta
        String laConsulta = "SELECT * FROM alumnos";
        Statement stmtConsulta = laConexion.createStatement();
        ResultSet rs = stmtConsulta.executeQuery(laConsulta);       
        // Muestra los datos
        while( rs.next() )
        System.out.println( "ID: " + rs.getInt("alu_id") + " -- " + "Nombre: " + rs.getString("alu_nombre") + " -- " + "Apellido: " + rs.getString("alu_apellido") );       
        // Cierra el Statement y la Connection
        stmtConsulta.close();
        laConexion.close();


Como insertar datos

El método createStatement()

      El método createStatement() es el mismo presentado en la sección Consulta.

El método execute()
      El método execute() se utiliza para ejecutar sentencias SQL del tipo INSERT, UPDATE o DELETE, y a diferencia del método executeQuery() no retorna un conjunto de resultados.
      La forma de utilizar el método execute() es:
     
      String laInsercion = "INSERT INTO alumnos (alu_id, alu_nombre, alu_apellido) VALUES (101, 'Manuel', 'Santos')";

Como realizar una inserción

      // Define la conexión
        Connection laConexion = AdministradorDeConexiones.getConnection();   
        // Arma la sentencia de inserción y la ejecuta
        String laInsercion = "INSERT INTO alumnos (alu_id, alu_nombre, alu_apellido) VALUES (101, 'Manuel', 'Santos')";
        Statement stmtInsercion = laConexion.createStatement();
        stmtInsercion.execute(laInsercion);       
        // Cierra el Statement y la Connection
        stmtInsercion.close();
        laConexion.close();       
        // Informa que la inserción ha sido realizada con éxito
        System.out.println("La inserción ha sido realizada con éxito...");


Como actualizar datos

El método createStatement()

      El método createStatement() es el mismo presentado en la sección Consulta.

El método execute()
      El método execute() es el mismo presentado en la sección Insercion.

Como realizar una actualización
     
      // Define la conexión
        Connection laConexion = AdministradorDeConexiones.getConnection();       
        // Arma la sentencia de actualización y la ejecuta
        String laActualizacion = "UPDATE alumnos SET alu_apellido = 'Trobbiani' WHERE alu_id = 101";
        Statement stmtActualizacion = laConexion.createStatement();
        stmtActualizacion.execute(laActualizacion);       
        // Cierra el Statement y la Connection
        stmtActualizacion.close();
        laConexion.close();       
        // Informa que la actualización ha sido realizada con éxito
        System.out.println("La actualización ha sido realizada con éxito...");


Como eliminar datos

El método createStatement()

      El método createStatement() es el mismo presentado en la sección Consulta.

El método execute()
      El método execute() es el mismo presentado en la sección Insercion.

Como realizar una eliminación

      // Define la conexión
        Connection laConexion = AdministradorDeConexiones.getConnection();       
        // Arma la sentencia de eliminación y la ejecuta
        String laEliminacion = "DELETE FROM alumnos WHERE alu_id = 101";
        Statement stmtEliminacion = laConexion.createStatement();
        stmtEliminacion.execute(laEliminacion);       
        // Cierra el Statement y la Connection
        stmtEliminacion.close();
        laConexion.close();       
        // Informa que la eliminación ha sido realizada con éxito
        System.out.println("La eliminación ha sido realizada con éxito...");

Como tratar excepciones con el manejo de base de datos

public static void main(String[] args) {   
        // Declara el objeto de conexión
        Connection laConexion = null;       
        try
        {
            // Obtiene la conexión
            laConexion = AdministradorDeConexiones.getConnection();
            // Muestra los alumnos en pantalla
            mostrarAlumnos(laConexion);
        } catch(Exception e) {
            System.out.println( e.getMessage() );
        } finally {
            // Cierra la conexión
            try
            {
                if(laConexion != null)
                    laConexion.close();
            } catch(Exception e){}
        }
    }  

    public static void mostrarAlumnos(Connection conn) throws SQLException
    {
        Statement stmtAlumnos = null;     
        // Arma la sentencia SQL en forma de text
        String consulta = "SELECT * FROM alumnos";
        // Arma la sentencia SQL y la ejecuta
        stmtAlumnos = conn.createStatement();
        ResultSet rs = stmtAlumnos.executeQuery( consulta );
        // Muestra los alumnos en pantalla
        while(rs.next())
            System.out.println( rs.getString("alu_nombre") + " -- " + rs.getString("alu_apellido") );
    }



Transacciones

¿Que es un DAO?
         Cuando se pretende modelar con objetos de un modelo de datos, es decir las tablas y sus relaciones, es muy común utilizar una propuesta simple que consiste en armar una clase por cada tabla existente.
         Dicha clase tendrá los métodos de acceso a la tabla correspondiente, entre ellos la inserción, modificación y la eliminación. Este tipo de clases suelen conocerse como DAOs, ya que objetos de esta clase se utilizaran para realizar operaciones de datos.
         De esta forma, si existe la tabla autos, es posible construir una clase denominada Auto, que siguiendo la especificación de un DAO, se debería tener los métodos insertar, modificar, eliminar y métodos con las consultas que resulten necesarias.

¿Qué es una transacción?
         Una transacción en SQL es una colección de sentencias DML que forman una unidad lógica de trabajo o procesamiento, con propiedades bien definidas. De esta manera será un conjunto de operaciones sobre los datos en una base de datos que o se ejecuta entera o no se ejecuta ninguna de sus sentencias.
         JDBC permite que las declaraciones de SQL sean agrupadas juntas en una sola transacción. De esta manera, es posible asegurar la atomicidad y consistencia de datos, usando características transaccionales de JDBC.

El método setAutoCommit()
         El control de la transacción es realizado por el objeto de la conexión. Cunado se crea una conexión, por defecto esta en el modo activado. Esto significa que cada declaración individual de SQL es tratada como transacción por sí
 mismo, y será comprometida tan pronto como finalice la ejecución.
         El método setAutoCommit es el encargado de establecer si se trabajara agrupando varias sentencias en una transacción, o por el contrario cada sentencia SQL será una transacción independiente.
         Para trabajar con varaias sentencias SQL y ejecutarlas como una transacción es necesario establecer el atuo-commit en false:
        
         unaConexion.setAutoCommit(false);

         Si no es necesario trabajar con transacciones, por defecto el auto-commit esta seteado en true.

El método commit
         Cuanto el auto-commit esta en false, para poder comprometer o impactar los cambios en la base de datos, es necesario llamar al método commit(). Si no se llama al método commit(), los cambios no serán reflejados en la base de datos aun cuando se hayan ejecutadas una o más sentencias SQL.
         El método commit() pertenece a la conexión, y la forma de invocarlo es la siguiente:
        
         unaConexion.commit();

El método rollback()
         Si en algún punto antes de invocar el método commit(), el método rollback() es invocado, todas las  sentencias que se hayan ejecutado quedaran sin efecto, es decir que el rollback() vuelve atrás todos los cambios realizados sobre los datos desde el ultimo commit() realizado.
         El método rollback() también pertenece a la conexión, y la forma de invocarlo es la siguiente:
        
         una Conexión.rollback()

Utilización de transacciones

         // Declara la conexión
        Connection conn = null;       

       //Declara los alumnos a insertar
         Alumno a1 = new Alumno(“Juan”);
         Alumno a2 = new Alumno(“Pedro”);
         Alumno a3 = new Alumno(“Mario”);
        try{
            // Define la conexión
            conn = AdministradorDeConexiones.getConnection();           
            // Setea el auto-commit en falso
            conn.setAutoCommit(false);           
             //Acá comienza la transacción
             a1.insertar(conn);
             a2.insertar(conn);
             a3.insertar(conn);            
            // Confirma los cambios
            conn.commit();

        } catch(Exception e) {
            try{

                // Vuelve atras los cambios
                conn.rollback();

            } catch(Exception ee){//Manejo de errores}
        } finally{
            try{

                // Cierra la conexión
                if( conn != null )
                    conn.close();

            } catch(Exception e){//Manejo de errores}
        }

14 comentarios:

  1. GRACIAS BROTHER ME SIRVIO DE MUCHO

    ResponderEliminar
  2. HOLA NECESITO LA CONFIGURACION DE CONEXION BD CN NETBEANS
    GRASIAS

    ResponderEliminar
  3. hola como puedo usar un show tables y me muestre datos o un show databases

    ResponderEliminar
  4. hola !, una pregunta, cuando te refieres al metodo de la coneccion .close(), donde esta ese programado ?

    ResponderEliminar
  5. que CULERAMENTE claro es el mejor blog men gracias

    ResponderEliminar
  6. Esto esta muy bien, pero también sería conveniente saber como insertar desde un fichero externo previamente recorrido, el ej es insertar los datos de los partidos de fútbol de cada jugador. Espero que os sirva
    A continuación os dejo un pequeño código explicándolo:

    public void insertarEnBD(List listaDetalle) throws ClassNotFoundException, SQLException {
    String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    String DB_URL = "jdbc:mysql://localhost/test";
    String USER = "";
    String PASS = "";
    Connection conn;
    PreparedStatement prepareStmt;

    //De aqui sacamos los datos, para insertarlos en BBDD
    InfoPartido infoPartido = new InfoPartido();
    List partidos = infoPartido.getListadoDetallePartidos();

    try {
    conn = DriverManager.getConnection(DB_URL, USER, PASS);

    //insertar en detallePartido: idpartido, idjugador, goles, pases, asistencias
    String insertTableSQL = "insert into detallepartido (id_partido, id_jugador, goles, pases, asistencias) values (?,?,?,?,?)";

    for(DetallePartido p : partidos){
    prepareStmt = conn.prepareStatement(insertTableSQL);
    prepareStmt.setInt(1,p.getIdPartido());
    prepareStmt.setInt(2, p.getIdJugador());
    prepareStmt.setInt(3, p.getGoles());
    prepareStmt.setInt(4,p.getPases());
    prepareStmt.setInt(5,p.getAsistencias());

    prepareStmt.executeUpdate();

    }

    System.out.println("Datos insertados correctamente");

    conn.close();
    } catch (SQLException e) {
    System.err.println(e.getMessage());
    }
    }

    ResponderEliminar
  7. public class ConexionDB {
    public static Connection GetConnection()
    {
    Connection conexion = null;

    try
    {
    Class.forName("com.mysql.jdbc.Driver");
    String servidor = "jdbc:mysql://localhost/bdProductos";
    String usuarioDB = "root";
    String passwordDB = "";
    conexion = DriverManager.getConnection(servidor,usuarioDB,
    passwordDB);
    }
    catch(ClassNotFoundException ex)
    {
    conexion = null;
    }
    catch(SQLException ex)
    {
    conexion = null;
    }
    catch(Exception ex)
    {
    conexion = null;
    }
    finally
    {
    return conexion;
    }
    }
    }

    ResponderEliminar
  8. public ArrayList recuperarMonuments() throws SQLException{
    ArrayList monuments = new ArrayList<>();

    try{
    Statement st = conn.createStatement();

    String consulta = "SELECT * FROM monuments;";
    ResultSet rs = st.executeQuery(consulta);
    while(rs.next()){
    int idMonument = rs.getInt("id_monument");
    String nomMonument = rs.getString("nom_monument");
    int anyAlta = rs.getInt("any_alta");
    char idTipus = rs.getString("id_tipus").charAt(0);
    int idComunitat = rs.getInt("id_comunitat");
    String nomFoto = rs.getString("nom_foto");

    String nomComunitat = recuperarComunitat(idComunitat).getNom();
    Comunitat comunitat = new Comunitat(idComunitat, nomComunitat);
    String nomTipus = recuperarTipus(idTipus).getNom();
    TipusMonument tipus = new TipusMonument(idTipus, nomTipus);

    Monument monument = new Monument(idMonument, nomMonument,
    anyAlta, tipus, comunitat, nomFoto);
    monuments.add(monument);
    }
    }catch(SQLException e){
    throw new SQLException("No s'han pogut recuperar els monuments " +
    "de la taula monuments.");
    }

    return monuments;
    }

    ResponderEliminar
  9. public ArrayList recuperarComunitats() throws SQLException{
    ArrayList comunitats = new ArrayList<>();

    try{
    Statement st = conn.createStatement();

    String consulta = "SELECT * FROM comunitats;";
    ResultSet rs = st.executeQuery(consulta);

    while(rs.next()){
    int idComunitat = rs.getInt("id_comunitat");
    String nom = rs.getString("nom_comunitat");
    Comunitat comunitat = new Comunitat(idComunitat, nom);
    comunitats.add(comunitat);
    }
    }catch(SQLException e){
    throw new SQLException("No s'han pogut recuperar les comunitats " +
    "de la taula comunitats.");
    }

    return comunitats;
    }

    ResponderEliminar