Diferencia entre revisiones de «Prog Acceso a base de datos relacionales»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 140: Línea 140:
 
: 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.
 
: 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 [https://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html en este enlace] el uso de '''parámetros varargs''' que son los que aparecen en el ejemplo con tres puntos ('''...''')
 
: Podéis consultar [https://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html 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 [http://wiki.cifprodolfoucha.es/index.php?title=Prog_Estructuras_de_almacenamiento#Colecciones Colección].
 +
: Veamos un ejemplo:
 +
 +
::<syntaxhighlight lang="java" line enclose="div" highlight="" >
 +
            String update = "INSERT INTO alumnos (nombre,f_nacimiento) VALUES (?,?)";
 +
            PreparedStatement ps = con.prepareStatement(update);
 +
            ArrayList<Object>params = new ArrayList();
 +
            params.add("Manuela2");
 +
            params.add(new Date());
 +
           
 +
            int indice = 1;
 +
            for(Object par : params){
 +
                if (par instanceof String) {
 +
                    ps.setString(indice, (String)par);
 +
                }
 +
                if (par instanceof Date){
 +
                    java.sql.Date dataSQL = new java.sql.Date(((Date)par).getTime());
 +
                    ps.setDate(indice, dataSQL);
 +
                }
 +
                indice++;
 +
            }
 +
            ps.executeUpdate();
 +
</syntaxhighlight>
  
 
==Inserción==
 
==Inserción==

Revisión del 14:49 2 may 2018

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.


  • 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


  • 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 update = "INSERT INTO alumnos (nombre,f_nacimiento) VALUES (?,?)";
 2             PreparedStatement ps = con.prepareStatement(update);
 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             ps.executeUpdate();

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).