Prog Acceso a base de datos relacionales
Sumario
Introdución
Descargando las librerías para conectar a Mysql
- Debemos ir a este enlace.
- 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.
- 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
- En caso de llevar parámetros y para evitar ataque con inyección de código, debemos hacer uso de la clase PreparedStatement.
- Un ejemplo de uso en este enlace.
- 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 (...)
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.
- Para ejecutar una orden perteneciente al DML tenemos que llamar al método executeUpdate(java.lang.String).
- 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.
- Para ejecutar una orden perteneciente al DML tenemos que llamar al método executeUpdate(java.lang.String).
- 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.
- La orden SQL para actualiza datos es UPDATE.
- La orden DELETE pertenece a la categoría de [https://es.wikipedia.org/wiki/Lenguaje_de_manipulaci%C3%B3n_de_datos Lenguaje de Manipulación de Datos o DML).
- Para ejecutar una orden perteneciente al DML tenemos que llamar al método executeUpdate(java.lang.String).
- 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 update = "DELETE FROM alumnos 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();
-- Ángel D. Fernández González -- (2017).