Prog Acceso a base de datos relacionales

De MediaWiki
Saltar a: navegación, buscar

Introdución


Descargando las librerías para conectar a Mysql

Nota: Estos pasos están probados en un Linux Mint 18 (basado en Ubuntu 16.04) de 64bits.


  • Si descargamos el paquete deb, las librerías necesarias se instalarán el el directorio /usr/share/java. El fichero (en este caso) es mysql-connector-java-8.0.11.jar.
Prog db rel 1.jpg


  • Si queremos desarrollar una aplicación desde NetBeans, debemos de añadir el jar a las librerías del proyecto como vimos en este punto de la wiki.
  • Si queremos ejecutar desde consola la aplicación ya compilada (el class) o compilarla desde otro editor, tendremos que modificar la variable de entorno classpath para añadir el jar, como está indicado en este enlace.


  • La librería descargada, obliga a que el servidor Mysql tenga establecido el huso horario. Podríamos indicarlo en la cadena de conexión desde el cliente java con la siguiente línea:
useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
O bien ejecutar la orden SQL: SET GLOBAL time_zone = '+1:00'



Trabajando contra una base de datos Mysql

  • Lo primero que tenemos que hacer es realizar una conexión a la base de datos.
Entre los datos que vamos a necesitar estarán:
  • Usuario para conectarse a la base de datos con permisos para realizar las operaciones que necesitemos.
  • Password del usuario.
  • Nombre de la base de datos a la que nos vamos a conectar.
  • Nombre del host donde está instalado el servidor Mysql.
  • La cadena de conexión que representa una conexión a un servidor Mysql en JDBC.
  • En la versión en la que estamos trabajando hay que añadir dos opciones más:
  • Una en la que se le indica el huso horario.
  • Otra opción en la que se le indica que no se va a conectar utilizando una conexión segura (SSL), ya que si no lo indicamos, aparecerá un warning.


  • Veamos un ejemplo de código:
  1.         try {
  2.             String servidor = "localhost";
  3.             String basedatos = "ejemplo";
  4.             String user = "root";
  5.             String password = "root";
  6.            
  7.             String husoHorario = "useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
  8.             String noUsarSSL = "&useSSL=false";
  9.  
  10.             String cadenaConexion = String.format("jdbc:mysql://%s/%s?%s%s",servidor,basedatos,husoHorario,noUsarSSL);
  11.  
  12.             Connection conexion = DriverManager.getConnection(cadenaConexion,user,password);
  13.  
  14.  
  15.         }  catch (SQLException ex) {
  16.             Logger.getLogger(ConsultaSimple.class.getName()).log(Level.SEVERE, null, ex);
  17.         }


  • En versiones anteriores del conector JDBC, era necesario cargar el controlador que representaba la conexión al gestor Mysql con las siguientes instrucciones:
  1.         try {
  2.             Class.forName("com.mysql.jdbc.Driver");
  3.         } catch (ClassNotFoundException e) {
  4.  
  5.         }
Ahora ya no es necesario, a parte de que la clase que carga el driver ya no es la anterior, es com.mysql.cj.jdbc.Driver


  • Una vez realizadas las operaciones contra la base de datos, se llama al método close() del objeto de la clase Connection:
  1. conexion.close();



Consultas

  • Partimos siempre que tenemos definido previamente un objeto de la clase Connection conectado a la base de datos.
  • El proceso a seguir es:
  • Debemos de crear un objeto de la clase Statement, llamando al método createStatement() del objeto Connection.
  • Llamamos al método executeQuery(consulta) pasando como parámetro la consulta a realizar. Dicha llamada devolverá un objeto de la clase ResultSet.
  • Ese objeto ResultSet representa el contenido de los datos devueltos por la base de datos. Para nosotros será como una tabla que tendremos que recorrer fila a fila en un bucle obteniendo por cada fila los datos de la consulta (lo que vendrían a ser las columnas). Para ello necesitamos llamar al método next() del objeto ResultSet el cual devolverá true en caso de que haya aún datos que recorrer y además 'apuntará' a la siguiente fila del conjunto de resultados. Para recoger los datos de la fila actual debemos llamar al método getXXXX(“columna”) siendo XXXX el tipo de dato que queramos leer y “columna” el nombre de la columna utilizada en la consulta (el select)


  • Veamos un ejemplo:
  1.             Statement consulta = conexion.createStatement();
  2.             ResultSet resultados = consulta.executeQuery("SELECT nombre,f_nacimiento FROM alumnos");
  3.             while(resultados.next()) {
  4.                 Date fechaBD = resultados.getDate("f_nacimiento");
  5.                 String fechaSpain = new SimpleDateFormat("dd-MM-yyyy").format(fechaBD);
  6.                 System.out.printf("Nombre:%s----F_nac:%s%n",resultados.getString("nombre"),fechaSpain);
  7.             }
  8.  
  9.             resultados.close();
Al igual que la conexión, se debe llamar al método close() de la clase ResultSet para liberar los recursos.


  • Podemos llamar a procedimientos almacenados poniendo como orden a ejecutar CALL y el nombre del procedimiento, de la siguiente forma:
  1. ResultSet resultados = consulta.executeQuery("CALL alumno_listar()");
Siendo alumno_listar() un procedimiento con el siguiente código:
  1. DELIMITER $$
  2. CREATE DEFINER=`root`@`localhost` PROCEDURE `alumno_listar`()
  3.     NO SQL
  4. SELECT nombre,f_nacimiento
  5. FROM alumnos
  6. ORDER BY nombre$$
  7. DELIMITER ;


De todas formas, si el procedimiento lleva parámetros es mejor hacer la llamada utilizando la clase CallableStatement.
Podéis consultar un ejemplo en este enlace.


Consultas con parámetros

  • El objeto de la clase PreparedStatement(consulta) lleva la consulta a realizar pero en vez de indicar los valores a utilizar por la consulta, se sustituyen dichos valores por el símbolo: ?. Por ejemplo, si quiero hacer una consulta buscando por el valor de un dni, dicha consulta tendrá en la parte where: WHERE dni = XXXXXXX. En este caso tenemos un parámetro que es el valor del campo dni a buscar.
Si tenemos dos parámetros, tendremos dos interrogaciones. Después deberemos de llamar al método setXXXX(posicion,valor) del objeto PreparedStatement, siendo posición el número de parámetro en la consulta, empezando siempre en la posición uno, y 'valor' el valor que vamos a enviar al parámetro.



  • Si queremos tener una forma genérica de ejecutar órdenes SQL con parámetros tenemos un ejemplo de como hacerlo en este enlace.
Básicamente enviamos a un método un conjunto de parámetros. Cada parámetro es analizado para obtener su tipo y así llamar al método setXXXXX, siendo XXXXX el tipo del parámetro.
Podéis consultar en este enlace el uso de parámetros varargs que son los que aparecen en el ejemplo con tres puntos (...)


También podemos hacerlo con un ArrayList u otra Colección.
Veamos un ejemplo:
  1.             String select = "SELECT nombre FROM alumnos WHERE nombre = ? and f_nacimiento = ? ORDER BY nombre";
  2.             PreparedStatement ps = con.prepareStatement(select);
  3.             ArrayList<Object>params = new ArrayList();
  4.             params.add("Manuela2");
  5.             params.add(new Date());
  6.            
  7.             int indice = 1;
  8.             for(Object par : params){
  9.                 if (par instanceof String) {
  10.                     ps.setString(indice, (String)par);
  11.                 }
  12.                 if (par instanceof Date){
  13.                     java.sql.Date dataSQL = new java.sql.Date(((Date)par).getTime());
  14.                     ps.setDate(indice, dataSQL);
  15.                 }
  16.                 indice++;
  17.             }
  18.             ResultSet resultado = ps.executeQuery();

Inserción

  • Partimos siempre que tenemos definido previamente un objeto de la clase Connection conectado a la base de datos.
En todos los ejemplos vamos a utilizar la orden PreparedStatement, pero se podría utilizar la orden CreateStatement.


  • La orden SQL para actualiza datos es INSERT.
La orden INSERT pertenece a la categoría de Lenguaje de Manipulación de Datos o DML.



  • Un ejemplo:
  1.             String servidor = "localhost";
  2.             String basedatos = "ejemplo";
  3.             String user = "root";
  4.             String password = "root";
  5.  
  6.  
  7.             String husoHorario = "useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
  8.             String noUsarSSL = "&useSSL=false";
  9.  
  10.             String conexion = String.format("jdbc:mysql://%s/%s?%s%s",servidor,basedatos,husoHorario,noUsarSSL);
  11.             Connection con = DriverManager.getConnection(conexion,user,password);
  12.  
  13.  
  14.             String insert = "INSERT INTO alumnos (nombre,f_nacimiento) VALUES (?,?)";
  15.             PreparedStatement ps = con.prepareStatement(insert);
  16.             ps.setString(1, "Manuela");
  17.             java.sql.Date dataSQL = new java.sql.Date(new Date().getTime());
  18.             ps.setDate(2, dataSQL);
  19.             ps.executeUpdate();
  20.  
  21.  
  22.             ps.close();
  23.             con.close();





Actualización

  • Partimos siempre que tenemos definido previamente un objeto de la clase Connection conectado a la base de datos.
En todos los ejemplos vamos a utilizar la orden PreparedStatement, pero se podría utilizar la orden CreateStatement.


  • La orden SQL para actualizar datos es UPDATE.
La orden UPDATE pertenece a la categoría de Lenguaje de Manipulación de Datos o DML.


En el caso de la instrucción UPDATE, la llamada al método devuelve el número de filas afectadas por la actualización en la base de datos.


  • Un ejemplo:
  1.             String servidor = "localhost";
  2.             String basedatos = "ejemplo";
  3.             String user = "root";
  4.             String password = "root";
  5.  
  6.  
  7.             String husoHorario = "useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
  8.             String noUsarSSL = "&useSSL=false";
  9.  
  10.             String conexion = String.format("jdbc:mysql://%s/%s?%s%s",servidor,basedatos,husoHorario,noUsarSSL);
  11.             Connection con = DriverManager.getConnection(conexion,user,password);
  12.  
  13.  
  14.             String update = "UPDATE alumnos SET nombre='Carla' WHERE id=?";
  15.             PreparedStatement ps = con.prepareStatement(update);
  16.             ps.setInt(1, 1);                                      // EL índice empieza en 1
  17.             int numFilasAfectadas = ps.executeUpdate();
  18.             System.out.printf("Número de filas afectadas:%d%n",numFilasAfectadas);
  19.  
  20.             ps.close();



Borrado

  • Partimos siempre que tenemos definido previamente un objeto de la clase Connection conectado a la base de datos.
En todos los ejemplos vamos a utilizar la orden PreparedStatement, pero se podría utilizar la orden CreateStatement.


  • La orden SQL para actualiza datos es UPDATE.
La orden DELETE pertenece a la categoría de Lenguaje de Manipulación de Datos o DML.


En el caso de la instrucción DELETE, la llamada al método devuelve el número de filas borradas en la base de datos.


  • Un ejemplo:
  1.             String servidor = "localhost";
  2.             String basedatos = "ejemplo";
  3.             String user = "root";
  4.             String password = "root";
  5.  
  6.  
  7.             String husoHorario = "useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
  8.             String noUsarSSL = "&useSSL=false";
  9.  
  10.             String conexion = String.format("jdbc:mysql://%s/%s?%s%s",servidor,basedatos,husoHorario,noUsarSSL);
  11.             Connection con = DriverManager.getConnection(conexion,user,password);
  12.  
  13.  
  14.             String delete = "DELETE FROM alumnos WHERE id=?";
  15.             PreparedStatement ps = con.prepareStatement(delete);
  16.             ps.setInt(1, 1);                                      // EL índice empieza en 1
  17.             int numFilasAfectadas = ps.executeUpdate();
  18.             System.out.printf("Número de filas afectadas:%d%n",numFilasAfectadas);
  19.  
  20.             ps.close();




-- Ángel D. Fernández González -- (2017).