Empezando con MySQL y Java

MySQL es una base de datos muy popular, y fuertemente recomendada tanto para programación web  como para programación general. A pesar de ser gratuida es muy estable y muy práctica para trabajar con diferentes aplicaciones. En este caso, la idea es hacer un ejemplo muy básico trabajando la consulta SELECT para una base de datos en MySQL dese Java.

Java permite establecer una conexión con MySQL con llamadas de unas simples líneas. Para crear la conexión entre la base de datos y java vamos a necesitar el conectot que nos ofrece mysql, se puede bajar aquí. Suponiendo que ya tienen su conector en la caperta de librerias de su proyecto de java, y MySLQ instalado pues empezamos con el trabajo.

1. Estableciendo la conexión
2. Consulta Select
3. Extraer la información del ResulSet
4. Otros tipos de Select

Estableciendo la conexión

Cuando instalamos mysql, durante la instalación hemos recopilado una serie de datos que son de suma importancia. estamos hablando del usuario y la contraseña de la base de datos, además de eso, tambien debemos disponer del nombre del base de datos con la cual vamos a trabajar. En resumen  vamos a necesitar:

  1. usuario
  2. contraseña
  3. nombre de la base de datos
  4. host  ( si nuestra base de datos esta en nuestra pc entonces el nombre del host es localhost )
  5. puerto (si se ha instalado mysql de la forma convencional entonces el numero de puerto 3306 a menos que le hayan cambiado manualmente)

Ya sea que hagamos la conexión en una clase aparte un el mismo main, la conexión se crea de la misma forma de la siguiente forma:

Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/nombre_base_de_datos", "usuario", "contraseña");

Si notan, el metodo getConnection contiene un String que toma los datos que mencionamos anteriormente y lo convierte en una URL válida para crear la conexion. Si todo va bien entonces solo queda preparar la consulta y ejecutarla.

Consulta Select

Vamos a empezar con crear una un método llamado consulta_select que va a tener la tarea de crear un select  a la base de datos. Está es la parte donde entramos a lo mas serio, y es que hay que tener claro ciertos aspectos antes de ejecutar comandos SQL desde java. Suponiendo que ya se tiene conocimientos básicos en SQL yq ue debe diferenciar cuando una consulta solo extrae información o si una consulta modifica la base de datos, dependiendo de esas dos normativas vamos a usar metodos diferentes, para ejemplificar mejor:

  • SELECT: usar el método executeQuery en java para ejecutar la consulta, porque no altera la base de datos, solo extrae información
  • INSERT, UPDATE y DELETE: usar el método executeUpdate en java para ejecutar la consulta, porque estas consultas si modifican la información en la base de datos.

Por ahora esta un poco confuso, pero adelante será mas claro. Antes de continuar vamos a suponer que nuestra base de datos tiene las tablas Personas y Paises que tienen la información con la que vamos a trabajar.

tabla personas

id_persona nombre primer_apellido edad pais
1 frank malfoy 16 1
2 alis rodriguez 30 2
3 karen juarez 22 1
4 andrea fernandez 21 3
5 alesa benede 13 4
6 henry gonzalez 21 2
7 daniel hidalgo 16 1
8 roy castro 20 4
9 sabrina de la torre 18 2

tabla paises

id_pais nombre tamaño
1 chile grande
2 costa rica pequeño
3 mexico mediano
4 venezuela mediano

Las anteriores tablas tienen información muy básica, solo un detalle, nótese que hay una llave foránea desde la tabla Personas (pais) a la tabla Paises (id_pais).

Entonces, nuestro método consulta_select se va a encargar de generar la consulta “seleccionar todas las personas que se llamen frank”. Preparamos la consulta:

Statement consulta = (Statement) c.createStatement();
ResultSet resultado = consulta.executeQuery("select * from personas where nombre = 'frank'");

Con el el objeto c que lo creamos con la el objeto Statement que va a ser el encargado de ejecutar la consulta, dentro de ella la sentencia SQL. El resultado de dicha consulta de almacena en un objeto de tipo ResulSet, este objeto se comporta como un tabla virtual que contiene la información de la salida de la sentencia del select, es decir, el valor de resultado es:

1 frank malfoy 16 1

Para hacer un repaso de cómo quedó el método consulta_select tendríamos algo como esto:

public void consulta_select() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/mi_base_de_datos", "usuario", "contraseña");
Statement consulta = (Statement) c.createStatement();
ResultSet resultado = consulta.executeQuery("select* from personas where nombre = 'frank'");

//  aca se va a trabajar con el resultado (ResulSet)

} catch (SQLException ex) {
System.out.println("Hubo un error con los comandos SQL");
} catch (ClassNotFoundException ex2){
System.out.println("No se pudo cargar el driver");
}
}

Extraer la información del ResulSet

Siguiendo con el método anterior ya ahora solo falta extraer la información que almacena la variable resultado. Esta variable tiene la el nombre de cada columna según el resultado que arrojó la consulta, también tiene una serie de filas que tiene cada registro. Entonces, procedemos a extraer los datos:

int columna_id_persona = resultado.findColumn("id_persona");
int columna_nombre = resultado.findColumn("nombre");
int columna_edad = resultado.findColumn("edad");
int columna_pais = resultado.findColumn("pais");

boolean lleno = resultado.next();

while (lleno){
int id = resultado.getInt(columna_id_estudiante);
String nombre = resultado.getString(columna_nombre);
int edad = resultado.getInt(columna_edad);
int pais = resultado.getInt(columna_pais);
lleno = resultado.next();

System.out.println("id: " + id + "n" +
"nombre: " + nombre + "n" +
"edad: " + edad + "n"+
"pais: " + pais);
}

El código anterior tiene métodos muy variados, su funcionalidad depende mucho del tipo de información que contiene la cada columna.

  • findColumn(nombre_columna): busca el índice de la columna. Al saber el índice de la columna podemos saber que dato extraer exactamente. Por ejemplo, la columna 1 es la columna del id_persona, de lo cual ya sabemos que esa columna solo va tener datos de tipos numéricos. De igual forma para columna 2, que es la encargada de tener el nombre de las personas, en otras palabras, datos String
  • next(): este método nos índica si el resultado (ResulSet) esta vacío o no, es decir, retorna false. En caso de que estuviera vacío es porque la consulta SELECT no generó ningún resultado, pues ningún registro cumplía con todas las condiciones. Por otro lado, retorna true tiene registros, esta vaiable es usada por el ciclo para ir iterando entre cada registro
  • getInt(indice_columna), getString(indice_columna): Estos métodos ya extraen la información del resultado, según sea el tipo de dato ese será el método específico a llamar. Para el ejemplo de la tabla Personas solo tiene dos tipos de datos, numéricos y String, pero el API del ResulSet nos proporciona otros métodos si usamos tipos de datos como doble, date, long, etc.

Para finalizar, le método completo quedaría…

[cdoe='java']
public void consulta_select() {
try {
Class.forName(“com.mysql.jdbc.Driver”);
Connection c = DriverManager.getConnection(“jdbc:mysql://localhost:3306/mi_base_de_datos”, “usuario”, “contraseña”);
Statement consulta = (Statement) c.createStatement();
ResultSet resultado = consulta.executeQuery(“select* from personas where nombre = ‘frank’”);

int columna_id_persona = resultado.findColumn(“id_persona”);
int columna_nombre = resultado.findColumn(“nombre”);
int columna_edad = resultado.findColumn(“edad”);
int columna_pais = resultado.findColumn(“pais”);

boolean lleno = resultado.next();

while (lleno){
int id = resultado.getInt(columna_id_estudiante);
String nombre = resultado.getString(columna_nombre);
int edad = resultado.getInt(columna_edad);
int pais = resultado.getInt(columna_pais);
lleno = resultado.next(); //se verifica si hay otro registro

System.out.println(“id: ” + id + “n” +
“nombre: ” + nombre + “n” +
“edad: ” + edad + “n”+
“pais: ” + pais);
}

} catch (SQLException ex) {
System.out.println(“Hubo un error con los comandos SQL”);
} catch (ClassNotFoundException ex2){
System.out.println(“No se pudo cargar el driver”);
}
}
[/code]

La salida de ejemplo seria:

id: 1
nombre: frank
edad: 16
pais: 1

Otra manera mas corta de hacer el métod es eliminar los índices de las columnas, y los métods getString y getInt es pasarle el nombre o el índice de la columna directamente, ejemplo:

//asi:
String nombre = resultado.getString("nombre");

//o asi:
int edad = resultado.getInt(4);

Otros tipos de Select

A veces cuando trabajamos con varias tablas, la mayoría de las veces exite una relación entre ellas, esta relación natural se hace a travez de llaves foráneas (lo recomendado), esto es con el fin de que tengamos un mejor diseño de la base de datos.
Siguiendo con el ejemplo de las tablas anterios de Personas y Paises podemos observar que la su relación es a través de pais y del id_pais respectivamente. Entonces, supogamos que queremos todos los nombres de las personas y el país al que pertenecen. Acá la trampa es que tanto la columna del nombre de las peronas y la columna del nombre se los paises se llaman igual, entonces veamos como se especifica cada cosa...

Statement consulta = (Statement) c.createStatement();
ResultSet resultado = consulta.executeQuery("select personas.nombre, pais.nombre from personas, paises where pais = id_pais");

El resultado de dicha consulta seria:

nombre nombre
frank chile
alis costa rica
karen chile
andrea mexico
alesa venezuela
henry costa rica
daniel chile
roy venezuela
sabrina costa rica

Ahora, acá hay un conflicto de nombres de columnas, el ResulSet no sabe diferenciar a cual columna referirse cuando le hablamos por nombre de columnas ya que dos columnas tiene el mismo nombre, es decir, nombre. En este caso hay que obtener los datos de la columna por el numero de columna. El conteo de columnas en el ResulSet empieza desde 1 y no desde 0 como es lo usuarial, entonces, para referirse al nombre de las personas y al nombre de las paises sería...

String nombre_persona = resultado.getString(1); // 1 = primera columna
String nombre_pais = resultado.getString(2); // 2 = segunda columna

12 comments

  1. Antes de todo: Gracias por tus aportes, son muy buenos, ahora yo estoy empezando a trabajar java, y estoy generando aplicaciones web cons jsp. Mi entorno de Trabajo es el siguiente:

    JDK: 1.4
    IDE: Eclipse 2.x
    JWS: JBoss 3.x
    SBD: MySQL 5.x

    El problema que me da es que no puedo conectar a la Base de Datos usando jdbc, me da un error de que no encuentra la clase, y solo he podido conectarlo por odbc. No se si mi versión del JDK tendra algo que ver en ese error, ya que en las notas de version de MySQL, vi algo por el estilo, pero no estoy muy seguro por no soy muy bueno en el ingles. Y la otra duda es que desventaja tengo en usar odbc en ves de jdbc, o es exatamente lo mismo?

    Gracias

  2. Hola @crow,

    Pon aca el error que te esta dando, asi vemos con mas detalle que pasa.

    En cuanto a las ventajas y desventajas puedes ver:

    1. ODBC está escrito en C
    2. el gestor de drivers ODBC y el propio driver han de ser instalados en todos los ordenadores
    3. JDBC está escrito en Java y permite obtener aplicaciones completas en Java (100% pure java)
    4. usando ODBC en BD grandes, el rendimiento puede disminuir al convertir llamadas Java a C y viceversa

    Pura vida

  3. Gracias por la ayuda, pero como me urgia entregar la aplicacion que estaba diseñando, por eso no puede mostrar el error que me tiraba cuando usal el jdbc. Pero Gracias por la ayuda, talvez en el futuro ponga el error, para que propongas soluciones a la comunidad.

    Por el momento me he topado con otro problema, y espero que puedas ayudarme

    Tengo una aplicaciones que mustra un reporte, para ser mas objetivo, son unas solvencias, Por el momento se muestran una JSP. El problema que desde alli, me es imposible configurarla para que se puedan imprimir correctamente (Algunas solvencias, salen una parte en una hoja, y otra parte en otra). Por lo que investigado acerca de reportes, en PDF.

    Y es alli donde quiero te ayuda, no se si usar el itext, o el jaspsereport/ireport. Ademas los que he visto, solo se dedican a mostrar datos que ellos ponene manualmente, es decir el progrma escriben: ventas, y en el reporte sale la palabra ventas. Y no ponen imagenes al reporte, algo esencial para mi,( Ya que tengo que mostrar el logotipo de la universidad, para cada solvencia)

    Si llegaste hasta aqui, gracias por tener paciencias para leer todo lo que escribi, y espero puedas darme alguna solucion, idea, o lo que sea, para que pueda terminar mi proyecto

    GRACIAS POR EL APOYO

  4. Hola que tal:
    Primero que nada gracias por tu aporte, esta muy bien explicado, solo que soy novato en el ambito JAVA/SQL y te comento lo que quiero lograr.
    Accesar a mi tabla creada ACCESO donde tengo 2 columnas Usuario: Y Contraseña: pero la verdad no supe y espero me resuelvas unas dudas al respecto de tu tutorial.

    Statement consulta = (Statement)c.createStatement();

    la variable c, donde es declarada? en mi compilador me dice “cannot find symbol”.

    String columna_usuario = resultado.findColumn(1);

  5. Hola…perdon!
    Todo tu codigo esta bien solo que como yo habia creado una funcion y a la hora de crear el objeto c

    public void conectarAcceso(){
    try{
    Class.forName(“com.mysql.jdbc.Driver”);
    Connection conexion = DriverManager.getConnection(“jdbc:mysql://localhost/acceso”,”root”,”");
    }
    catch(SQLException msgerror){
    msgerror.printStackTrace();
    System.exit(1);
    }
    catch(ClassNotFoundException Classe){
    Classe.printStackTrace();
    System.exit(1);
    }

    }

  6. Pero Muchas gracias por tu aporte! Me ayudo muchisimo!…ESpero sigas sibiendo cosas…ME INTERESA ESTUDIAR MAS:p…. SALUDOS

  7. hola que tal sabes soy residente y la verdad tengo un proyecto de conecyar una bd de un lector a otra en java la verdad no se como comenzar me ayudarias en ello

  8. que gestor de base de datos me recomendarias para trabajar en java para trabajar invwntario insumos productos trerminados clientes proveedores y no es algo alo k se le ingresaria demasiada info

  9. public class Conexion_DB {
    public Connection conex = null;
    // private Statement stm = null;

    public void Abrir_Conexion(){

    String usuario = “root”;
    String clave = “mysql”;
    String db = “banco”;
    String url = “jdbc:mysql://localhost/”+db;
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    conex = DriverManager.getConnection(url,usuario,clave);
    if (conex.equals(null)){
    System.out.println(“Error: al establecer conexion…”);
    // stm=conex.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    // ResultSet.CONCUR_UPDATABLE);
    }
    } catch (Exception e) {
    System.out.println(“Hubo un problema al intentar conectarse con la base de datos”);
    }
    }
    public void cerrar_conexion(){
    try {
    conex.close();
    System.out.println(“Conexion cerrada”);
    }catch(Exception e){
    System.out.println(“Error al cerrar la conexion”);
    }
    }
    }

  10. INSERTAR REGISTROS
    ——————-
    Conexion_DB var_conexion = new Conexion_DB();
    var_conexion.Abrir_Conexion();
    Statement stm;
    try {
    stm = var_conexion.conex.createStatement();
    String sql;
    sql = “INSERT INTO ahorros (“;
    sql += “aho_Cta” + “,”;
    sql += “Aho_Titular” + “,”;
    sql += “Aho_Fecha” + “,”;
    sql += “Aho_Tipo” + “,”;
    sql += “Aho_Saldo”;
    sql += “)”;
    sql += ” VALUES(“;
    sql += “‘” + this.Aho_Cta.getText() + “‘,”;
    sql += “‘” + this.Aho_Titular.getText() + “‘,”;
    sql += “‘” + this.Aho_Fecha.getText() + “‘,”;
    sql += “‘” + this.Aho_Tipo + “‘,”;
    sql += “‘” + Double.parseDouble(this.Aho_Saldo.getText()) + “‘”;
    sql += “)”;
    stm.executeUpdate(sql);
    JOptionPane.showMessageDialog(null, “Registro guardado con éxito …”, ” .::MENSAJE::.”, JOptionPane.INFORMATION_MESSAGE);

    } catch (SQLException ex) {
    System.out.print(“Error: “+ ex.getMessage());
    }
    }

  11. MODIFICAR REGISTRO
    ————————————————–
    Statement stm;
    ResultSet rs;
    if (this.Aho_Cta.getText().equals(“”)){
    JOptionPane.showMessageDialog(null,”Ingrese Codigo…”);
    }
    try{
    Conexion_DB var_conexion = new Conexion_DB();
    var_conexion.Abrir_Conexion();
    String sql = “SELECT * FROM ahorros WHERE Aho_Cta = ‘” + Aho_Cta.getText() + “‘”;
    stm = var_conexion.conex.createStatement();
    rs = stm. executeQuery(sql);
    if( rs != null ) {
    while(rs.next() ) {
    this.Aho_Titular.setText(“”+rs.getString(“Aho_Titular”));
    this.Aho_Fecha.setText(“”+rs.getString(“Aho_Fecha”));
    if (rs.getString(“Aho_Tipo”).equals(“$”)){
    this.Aho_Tipo_dolares.setSelected(true);
    }
    if (rs.getString(“Aho_Tipo”).equals(“S”)){
    this.Aho_Tipo_soles.setSelected(true);
    }
    this.Aho_Saldo.setText(“”+rs.getString(“Aho_Saldo”));
    }
    var_conexion.cerrar_conexion();
    }else{
    JOptionPane.showMessageDialog(null,”Ningun dato Encontrado”,”Mensaje de Informacion”,JOptionPane.PLAIN_MESSAGE);
    }
    }catch (Exception ex){
    System.out.print(“Error: “+ ex.getMessage());
    }

Leave a Reply