Este documento resume el API JDBC y el mapeo de objetos de bases de datos a clases Java. Brevemente describe los tipos de controladores JDBC, el uso de bloques try-catch para manejar excepciones, y cómo crear clases que representen las tablas de una base de datos, con atributos y métodos para acceder a los datos.
1. PROGRAMACIÓN ORIENTADA A OBJETOS
PROGRAMACIÓN ORIENTADA A OBJETOS
APLICADA A BASES DE DATOS
APLICADA A BASES DE DATOS
Por
LAURA NOUSSAN LETTRY
API JDBC - Parte 2
Aviso Legal
El presente libro electrónico
se distribuye bajo
Attribution-NonCommercialNoDerivs 3.0 Unported
2. POO APLICADA A BASES DE DATOS
ÍNDICE
API JDBC – PARTE 2
Introducción
1. Excepciones en Java. Concepto. Bloques Try y Catch.
2. API JDBC. El Controlador JDBC, concepto, características y clases principales.
3. Vista de Negocio: Diseño de Clases para mapear las Tablas del Modelo
Relacional.
4. Vista de Aplicación: Formulario y Menú Simple para crear la conexión y aplicar
SQL DML.
1
2
3
10
FUENTES Bibliográficas Consultadas
1. Documentación Java en general:
The Java Tutorials:
http://docs.oracle.com/javase/tutorial
2. Documentación sobre Swing:
http://docs.oracle.com/javase/tutorial/uiswing/index.html
3. API JDBC:
http://www.oracle.com/technetwork/java/overview-141217.html
The Java Tutorial:
http://docs.oracle.com/javase/tutorial/jdbc/index.html
BIBLIOGRAFÍA para el Alumno
1.
Contenidos de esta Unidad
2.
Programas fuentes linkeados en el site web de la materia y que son
complementarios al contenido.
3.
Demás material bibliográfico linkeado en el sitio web de la materia.
(*)
ACTIVIDADES
Unidad 2
Parte 2
Tareas
Lectura, trabajos, prácticas propuestas en el Website de la Materia.
(*): En el Website de la materia:
http://www.lnoussanl.com.ar/javabd/
3. POO APLICADA A BASES DE DATOS
API JDBC – PARTE 2
INTRODUCCIÓN
Como ya saben, el API JDBC permite la conexión con cualquier RDBMS que
tenga implementado el Driver JDBC siguiendo las clases del API. Cabe aclarar
además, que el API es parte integrante de los primeros desarrollos de la
plataforma Java, mediante el paquete java.sql. Asimismo en la actualidad está
presente en los diferentes entornos o plataformas de desarrollo: JavaSE,
JavaME y JavaEE.
En esta parte abordamos el estudio del API JDBC, los diferentes tipos que
existen de controladores JDBC; el manejo de excepciones y una introducción a
las diferentes vistas que existirán en la aplicación.
Para ello aplicamos el mapeo a las tablas y creamos tablas base que
representan a los objetos Tabla, es decir, las necesitamos para poder llevar a
cabo consultas y actualizaciones de la base de datos.
El desarrollo de esta parte se lleva a cabo mediante un ejemplo didáctico que
utiliza la Base de Datos Escuela.
Como ya dijéramos en la primera parte, el uso del API JDBC no implica
modificar las clases bases que mapean a las tablas, pero sí implica crear la
estructura de clases necesarias que van a comunicarse con el API.
A largo del cursado iremos adaptando la vista de aplicación y reutilizando el
código. Debe quedar claro que la complejidad de las excepciones así como las
clases bases que mapean a las tablas pertenecen a la vista de negocio, es
decir la lógica que resuelve el problema: gestionar una aplicación para que
pueda actualizar una base de datos y efectuar consultas sobre sus objetos.
4. POO APLICADA A BASES DE DATOS
EXCEPCIONES EN JAVA. Concepto. Bloques Try y Catch.
ttr
Concepto
y
API JDBC
Las Excepciones en Java son eventos que se producen durante la ejecución del programa y donde se
produce la interrupción del flujo normal de instrucciones. Este sería el concepto básico de lo que es una
excepción.
Le
En java además las excepciones son objetos que tienen una jerarquía. La clase principal es la clase
Throwable que es hija directa de la clase Object.
En la POO hay que tener siempre presente que los métodos están definidos dentro de las clases
juntamente con los atributos; por lo tanto, cualquier problema que se presente en tiempo de ejecución,
se origina en un método.
us
san
Para manejar estos eventos es que Java tiene una estructura de clases que crean objetos de tipo
Exception y que se pueden o deben utilizar dentro del código para poder manejar estos eventos
inesperados.
El Tutorial Java expresa al respecto: “Cuando se produce un error dentro de un método, el método crea
un objeto y se lo entrega al runtime system. El objeto, llamado un objeto de excepción, contiene
información sobre el error, incluyendo su tipo y el estado del programa cuando se produjo el error. La
creación del objeto de excpeción y su entrega al runtime system, es lo que se denomina lanzar una
excepción.”[1]
Después de lanzarse la excepción, el sistema en ejecución (runtime system) intentará manejarlo, es decir
procesar el error para que el programa no se cuelgue. Para manejarlo el runtime system se basa en la
pila de llamadas (una lista ordenada de los métodos que habían sido llamados con anterioridad al método
donde se produjo la excepción)
au
ra
No
La imagen muestra la pila de llamadas, desde el
iniciador del programa hasta el método donde se
produjo el error. La lista roja típica, cuando se produce
un error, pues mostrará otros métodos que han sido
llamados, y que pueden o no tener manejadores de
excepciones.
Bloques try y catch
.L
La documentación es bastante clara: un código Java es válido en la medida que incluya el manejo de
excepciones donde debe incluirse. Esto implica que cuando programamos con Java debemos analizar
nuestro código y detectar aquél que podría arrojar excepciones. Por ejemplo, el manejo de datos es un
caso típico (basta ir a la documentación java para darse cuenta) el uso de archivos es otro ejemplo típico.
¿Qué pasa si un usuario ingresa un nombre de archivo que no existe? Pues si está previsto que esto
puede ocurrir, el sistema no se colgará si se ha previsto la excepción.
Pr
of
El código que puede generar una excepción debe ir incluido dentro de un bloque try. Este bloque debe ir
seguido de uno o más bloques catch. Cada uno de los métodos o bloques catch debe especificar el tipo de
excepción que puede atrapar y un manejador de eventos. Después del último bloque catch puede ir un
bloque finally que es opcional y contiene código que siempre se ejecutará, sea que haya ocurrido o no
una excepción.
try {
código
}
catch (ExceptionType1 var_Name) {
código
}
El API JDBC – parte 2 pág. 1/20
5. POO APLICADA A BASES DE DATOS
ttr
y
catch (ExceptionType2 var_Name) {
código
}
finally{
código
}
Le
También podemos utilizar la sentencia Throws que que nos permitiría lanzar una Excepción creada por
nosotros mismos y que queremos controlar mediante nuestro propio código.
API JDBC. El Controlador JDBC, concepto, características y clases principales
The Java Database Connectivity (JDBC)
El API JDBC nos posibilita tres cosas:
us
san
El API JDBC (Java Database Connectivity) es el estándar de la industria para la conectividad
independiente entre el leguaje de programación Java y un amplio rango de bases de datos basadas en
SQL, así como otros orígines de datos de tipos tabulares, como son por ejemplo las hojas de cálculo o los
archivos planos.
1) establecer una conexión con una base de datos o con un orígen de datos tabular
2)
Enviar sentencias SQL
3)
Procesar los resultados.
La arquitectura del API JDBC
No
El api tiene dos conjuntos principales de interfaces: el primero está dirigido a los programadores y el
segundo, que es de más bajo nivel, a aquellos que escriben los drivers o controladores para el API.
Nosotros, como programadores, utilizamos el conjunto de interfaces y objetos de nivel superior; en
cambio Oracle, IBM o Microsoft, empresas que han escrito controladores JDBC para sus bases de datos (y
los han escrito lógicamente en Java) han tenido que utilizar el conjunto de interfaces de más bajo nivel.
Pr
of
.L
au
ra
Las aplicaciones (de escritorio o las web) así como los Applets (uaunque en este caso no es
recomendable por cuestiones de seguridad) a través de los dirvers o controladores JDB. A los drivers
JDBC se los puede categorizar en 4 clases: drives JDBC puros,
Fuente: http://www.oracle.com/technetwork/java/overview-141217.html
El API JDBC – parte 2 pág. 2/20
6. POO APLICADA A BASES DE DATOS
y
Los diferentes tipos de JDBC, listados en forma descendentes en cuanto a su capacidad de comunicación
directa con el DBM (jdbc pruso) son:
Tipo 4: Direct-to-Database Pure Java Driver
ttr
Este tipo de driver convierte las llamadas JDBC a las sentencias de protocolo utilizados directamente por
el DBM, por lo tanto las llamadas o mensajes son directos entre la máquina cliente y el DBMS. Es lo más
práctico para el acceso
Le
Tipo 3: Pure Java Driver for Database Middleware
Driver JDBC para Middleware. Este tipo de driver traduce las llamadas JDBC al protocolo utilizado por el
software middleware del vendedor. Es decir, aquí hay un paso intermedio, a través del servidor
middleware, pero también es un controlador JDBC puro.
Tipo 2: Native API partly Java technology-enabled driver
us
san
Este tipo de driver convierte las llamadas JDBC en el lado del API cliente de la base de datos (Oracle,
Sybase, Informix, DB2 y otros DBMS). Como en el siguiente caso, este tipo de controlador requiere que
parte del código binario cargado en cada máquina cliente.
Tipo 1: JDBC-ODBC Bridge plus ODBC Driver
No
El Driver JDBC ODBD provee acceso JDBC a través de los drivers ODBC; aquí la comunicación no solo no
es directa sino que se tiene que manejar un Puente, donde el código binario ODBC tiene que ser cargado
en cada máquina cliente que utilice el driver JDBC-ODBC. La plataforma Java desde sus inicios ofrece un
driver PUENTE JDBC-ODBC que se suele utilizar en situaciones experimentales y cuando el proveedor de
la base de datos no ha provisto un driver para Java. Este es el caso, por ejemplo, si queremos conectar
una aplicación Java a una planilla Excel o a una base de datos Access.
Vista de Negocio: Diseño de Clases para mapear las Tablas del Modelo
Relacional.
La vista de negocio es aquella que resuelve el problema, en nuestro caso, poder manipular una base de
datos mediante una aplicación Java. Para ello es necesario poder mapear las tablas, objetos reales que
son permanentes, en objetos de la aplicación.
au
ra
Sin embargo, hay que aclarar que la vista de
aplicación, es decir, las pantallas que verá el
usuario, son las que se comunican con éste y
con los objetos java intermedios, que
gestionan a las clases base de java y a su vez
cómo estas se comunican con objetos de
bases de datos (conexión, sentencias,
resultados)
.L
La pregunta lógica es ¿Cómo mapear las
tablas de la base de datos a clases Java?
Pr
of
La forma profesional de hacerlo es modelando
todo el problema mediante el Lenguaje UML
(Unified Modeling Language), pero esto
excede el ámbito de nuestra materia. Baste
decir que utilizando UML se puede modelar
todo
el
sistema
mediante
diferentes
diagramas, uno de ellos el Diagrama de
Clases.
MER Base de Datos Escuela (EER Diagram MySQL WorkBench)
Si bien no vamos a utilizar Diagramas de Clases, sí podemos tener en cuenta que una clase que
representa a una tabla, por lo menos debe tener los mismos atributos que la tabla. La clase como
plantilla podrá tener más atributos pero no menos que los que tenga la tabla a la cual estamos
“mapeando”. Lógicamente, una tabla no tiene métodos, pero una clase pues debe tenerlos, por lo menos
el constructor y métodos que nos permitan acceder a los atributos. Aquí hay que tener en cuenta todo lo
visto sobre calificadores de acceso. El MER de la figura corresponde a nuestro ejemplo didáctico: la base
de datos Escuela.
El API JDBC – parte 2 pág. 3/20
7. POO APLICADA A BASES DE DATOS
En el MER podemos ver que tenemos 4 tablas y para hacer el Mapeo tendremos en cuenta los atributos
de cada una de ellas.
y
Hemos creado un nuevo proyecto del tipo JavaApplication. Creará lógicamente el runtime para la
aplicación, que por ahora lo dejaremos así.
ttr
Vamos a crear cada una de las clases base, es decir, aquellas que representarán a cada a de las tablas.
Hay que tener en cuenta que cuando implementamos el diseño lógico del DBMS en un diseño físico
partimos de las tablas primarias, así también se hará con las clases.
La siguiente imagen muestra el Proyecto.
Creación
del
proyecto.
Dejamos así la
clase
runtime.
Vamos a crear
las clases base,
es decir las que
tienen que ver
con la lógica del
negocio y que
reflejarán
nuestros
‘objetos’ tabla
Creamos un nuevo archivo (desde el
paquete principal) que será una clase java
Pr
of
.L
au
ra
No
us
san
Le
Desde el Package creamos una nueva clase java que llamaremos Materia (las tablas en plural, las clases
en singular, recuerden).
El API JDBC – parte 2 pág. 4/20
8. POO APLICADA A BASES DE DATOS
.L
au
ra
No
us
san
Le
ttr
y
El archivo recién creado
y que modificaremos
para mapear la tabla en
clase
Pr
of
Como podemos ver, la clase tiene tres atributos, con un tipo de datos concordante al que tiene la tabla.
También debe contar con un constructor, en este caso las variables de la lista de parámetros serán
pasados desde clases gestionadotas de nivel superior, que representarán formularios y/o llamadas desde
el Menú Principal.
También necesitamos dos métodos public para poder acceder a los atributos que son de tipo privados.
Así pues, tanto los atributos como los métodos, son básicos. Esto quiere decir, que con el avance del
proyecto por ahí se tengan que agregar otros atributos o métodos, pero los que están tienen que estar.
El API JDBC – parte 2 pág. 5/20
9. POO APLICADA A BASES DE DATOS
No
us
san
Le
ttr
y
Ahora pasaremos a hacer el mapeo de la tabla Localidades para crear la clase Localidad, que tiene ciertas
particularidades.
Aquí la única diferencia es que utilizamos el tipo de datos short de Java para representar al smallint de
MySQL
Ahora tendremos que seguir por la tabla Alumnos, ya que la tabla Notas es una tabla dependiente de dos
tablas y Alumnos sólo es dependiente de Localidades.
ra
Las clases Alumno y Nota pueden verse directamente desde el código de este proyecto que está
disponible en el sitio web de la materia.
au
Sí cabe hacer una aclaración importante y es que a las clases, salvo a Nota, le hemos agregado otro
constructor alternativo. Esto porque entre las clases java de nivel superior y las clases base a veces es
conveniente pasar el objeto encapsulado.
A continuación se presenta el listado del código de las clases base y de la clase runtime.
Archivo Materia.java
Pr
of
.L
1 package toi_mapeo_escuela_1;
2
3 /**
4 *
5 * @author Laura Noussan Lettry
6 */
7 public class Materia {
8 //atributos son privados para acceder a ellos a través de los métodos
9 //del objeto, y no desde fuera
10 private int idmateria;
11 private String nom_materia;
12 //Constructor: construirá el objeto Materia a través de las variables que
13 //pasaremos desde las clases de nivel superior
14 public Materia(int id, String n){
15
this.idmateria = id;
16
this.nom_materia = n;
17 }//fin constructor
18 //constructor con parámetro encapsulado
19 public Materia(Materia m) {
El API JDBC – parte 2 pág. 6/20
10. POO APLICADA A BASES DE DATOS
ttr
Le
}
// Métodos: necesitamos métodos public para poder acceder a los valores
//de los atributos
public int getIdMateria(){
return this.idmateria;
}//fin método getIdMateria
public String getNombreMateria(){
return new String(this.nom_materia);
}//fin método
//Estos son los métodos básicos. Con el desarrollo podríamos tener que
//crear otros métodos u otros atributos, que tienen que ver con la interacción
//entre los objetos.
//Método para pasar todo el objeto materia
public Materia getMateria(){
return this;
}
y
this.idmateria=m.idmateria;
this.nom_materia=m.nom_materia;
us
san
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 }
Archivo Localidad.java
Pr
of
.L
au
ra
No
1 package toi_mapeo_escuela_1;
2
3 /**
4 *
5 * @author Laura Noussan Lettry
6 */
7 public class Localidad {
8 //atributos básicos
9 private int idlocalidad;
10 private String nom_localidad;
11 private short cod_post;
12 //Constructor: las variables se pasan desde la clase gestionadora
13 public Localidad(int id, String n,short c){
14
this.idlocalidad=id;
15
this.nom_localidad=n;
16
this.cod_post=c;
17 }//fin constructor
18 //otro constructor para poder pasar un objeto ya construido
19 public Localidad(Localidad loc){
20
this.idlocalidad=loc.idlocalidad;
21
this.nom_localidad=loc.nom_localidad;
22
this.cod_post=loc.cod_post;
23 }
24 //métodos para recuperar los atributos
25 public int getIdLocalidad(){
26
return this.idlocalidad;
27 }//fin método getIdLocalidad
28 public String getNomLocalidad(){
29
return new String(this.nom_localidad);
30 }//fin método getNomLocalidad
31 public short getCodPost(){
32
return this.cod_post;
33 }//fin método getCodPost
34 //método para recuperar un objeto Localidad
35 public Localidad getLocalidad(){
36
return this;
37 }
38
39 }
El API JDBC – parte 2 pág. 7/20
11. POO APLICADA A BASES DE DATOS
ttr
Pr
of
.L
au
ra
No
us
san
Le
1 package toi_mapeo_escuela_1;
2
3 import java.util.Date;
4
5 /**
6 *
7 * @author Laura Noussan Lettry
8 */
9 public class Alumno {
10 //atributos
11 private int dni;
12 private String apellido;
13 private String nombre;
14 private Date fecha_nac;
15 private String email;
16 private String telefono;
17 private String direccion;
18 private int localidad;
19 //constructor: las variables son pasadas desde la clase gestionadora
20 public Alumno(int id, String a, String n, Date f, String e, String t, String d, int loc){
21
this.dni=id;
22
this.apellido=a;
23
this.nombre=n;
24
this.fecha_nac=f;
25
this.email=e;
26
this.telefono=t;
27
this.direccion=d;
28
this.localidad=loc;//tenemos que modificar la clase Localidad ya que nos conviene
29
//pasar todo el objeto encapsulado
30 }
31 //constructor alternativo para pasar un objeto ya creado
32 public Alumno(Alumno a){
33
this.dni=a.dni;
34
this.apellido=a.apellido;
35
this.nombre=a.nombre;
36
this.fecha_nac=a.fecha_nac;
37
this.email=a.email;
38
this.telefono=a.telefono;
39
this.direccion=a.direccion;
40
this.localidad=a.localidad;
41 }
42 public int getDni(){
43
return this.dni;
44 }
45 public String getApellido(){
46
return this.apellido;
47 }
48 public String getNombre(){
49
return this.nombre;
50 }
51 public Date getFechaNac(){
52
return this.fecha_nac;
53 }
54 public String getEmail(){
55
return this.email;
56 }
57 public String getTelefono(){
58
return this.telefono;
59 }
60 public String getDireccion(){
61
return this.direccion;
62 }
63 public int getLocalidad(){
64
return this.localidad;
65 }
66 public Alumno getAlumno(){
67
return this;
y
Archivo Alumno.java
El API JDBC – parte 2 pág. 8/20
12. POO APLICADA A BASES DE DATOS
y
68 }
69 }
Le
ra
No
us
san
1 package toi_mapeo_escuela_1;
2
3 /**
4 *
5 * @author Laura Noussan Lettry
6 */
7 public class Nota {
8 private int dni;
9 private int idmateria;
10 private float parcial_1;
11 private float parcial_2;
12
13 //constructor: variables pasadas desde la clase gestionadora
14 public Nota(int idA, int idM, float uno, float dos){
15
this.dni=idA;
16
this.idmateria=idM;
17
this.parcial_1=uno;
18
this.parcial_2=dos;
19 }
20 //métoso para obtener los datos
21 public int getAlumno(){
22
return this.dni;
23 }
24 public int getMateria(){
25
return this.idmateria;
26 }
27 public float getParcial_1(){
28
return this.parcial_1;
29 }
30 public float getParcial_2(){
31
return this.parcial_2;
32 }
33
34 }
ttr
Archivo Nota.java
Archivo TOI_Mapeo_Escuela_1.java (runtime)
Pr
of
.L
au
1 package toi_mapeo_escuela_1;
2
3 import java.util.Date;
4 import javax.swing.JOptionPane;
5
6 /**
7 *
8 * @author Laura Noussan Lettry
9 */
10 public class TOI_Mapeo_Escuela_1 {
11
12 /**
13
* @param args the command line arguments
14
*/
15 public static void main(String[] args) {
16
// Vamos a hacer una prueba
17
//creando una materia
18
Materia mat = new Materia(1,"Lengua");
19
//creando una Localidad
20
Localidad loc1=new Localidad(1,"Ciudad de Mendoza",(short)5500);
21
//creando un Alumno
22
Alumno alu1=new Alumno(10000,"Rodriguez","Marcos",new Date(1996/11/30),"nridriguez@hotmail.com","02614233566","San Martin 556",loc1.getIdLocalidad());
El API JDBC – parte 2 pág. 9/20
13. No
us
san
La siguiente figura muestra la ejecución del runtime
Le
ttr
23
//creando las notas
24
Nota not1=new Nota(alu1.getDni(),mat.getIdMateria(),8,8);
25
26
String cadena="Materia:nIdMateria: "+mat.getIdMateria()+"b Nombre de la Materia:
"+mat.getNombreMateria()+"n";
27
JOptionPane.showMessageDialog(null, cadena, "Materias", 1, null);
28
// para ver las notas
29
30
String cadena2 ="Apellido: "+alu1.getApellido()+" Nombre: "+alu1.getNombre()+"nMateria:
"+mat.getNombreMateria()+"nParcial 1: "+not1.getParcial_1()+"nParcial 2: "+not1.getParcial_2();
31
32
JOptionPane.showMessageDialog(null, cadena2, "Notas", 1, null);
33
34 }
35 }
y
POO APLICADA A BASES DE DATOS
Vista de Aplicación: Formulario y Menú Simple para crear la conexión y
aplicar SQL DML.
ra
Las clases anteriores son las clases base de la aplicación. Sin embargo faltan otras clases base que tienen
que ver con las operaciones sobre la base de datos: actualizar y consultar.
Por otro lado, en el ejemplo anterior el manejo o gestión de las clases base se lleva a cabo en el runtime,
que es un archivo simple que sirve para fines didácticos, pero no serviría para una aplicación real.
Las clases base se tienen que poder comunicar con las clases gestionadotas del API JDBC.
au
Asi pues vamos a crear otro proyecto que se llamará
Este proyecto tiene un formulario principal: un JFrame y dentro de éste tenemos un Menú que tiene dos
ítems: DBMS y Consultar. El primero nos permitirá conectarnos y desconectarnos del DBMS, mientras
que el segundo nos permitirá consultar las tablas.
.L
Crear un Menú
Pr
of
Crear un Menú es una tarea bastante fácil en Java. Hay
que tener en claro que se debe usar un contenedor para
el Menú: JMenuBar. Este componente se arrastra
fácilmente al JFrame.
Dentro de la barra de menú van los diferentes menú
(JMenu) y desde ellos se puede crear una jerarquía
mediante los JMenuItem (pueden ser de texto, botones
de radio, checkbox)
Los menú dentro de la barra de menú se pueden
arrastrar desde la Paleta de Controles Swing o bien
podemos posicionarnos sobre el contenedor o elemento y
utilizar el menú contextual que aparece al pulsar el botón
derecho del ratón sobre dicho contenedor o elemento la opción Agregar desde la Paleta:
El API JDBC – parte 2 pág. 10/20
14. POO APLICADA A BASES DE DATOS
y
La Barra de menú viene ya configurada con dos menú
por omisión: File y Edit.
Le
us
san
El menú contextual es muy poderoso ya que desde aquí
también podemos cambiar el nombre de la variable,
elegir los eventos que se activarán, etc. Sin embargo
desde la ventana de propiedades podemos acceder a
todas las propiedades, variables, código y eventos.
ttr
Para cambiar las etiquetas de estos menús nos sirve el
menú contextual (Edit Text) o bien la misma ventana de
propiedades.
ra
No
Los dos ítems se pueden configurar para cambiarle
el título (text) y el nombre de variable.
au
Hemos creado la estructura de Menú que se puede apreciar en la siguiente imagen.
.L
Es importante ahora tener control sobre estos
elementos y que además sirva al usuario.
Se exigirá en los prácticos, por ejemplo, que los
nombres de las variables sean representativos
de la funcionalidad del objeto.
Pr
of
Por ejemplo, los menú y submenú deberían
empezar con la palabra ‘mnu’ que indica
claramente que se trata de un menú o
submenú.
Aquí mostramos un ejemplo de que no sólo importa el programador y su código sino que también al
diseñar y programar no hay que olvidarse que las aplicaciones van dirigidas a usuarios finales.
El API JDBC – parte 2 pág. 11/20
15. POO APLICADA A BASES DE DATOS
Importante para el usuario
us
san
Le
ttr
y
Importante para el programador
Ventana Propiedades, sección Propiedades:
No
Ventana Propiedades del Item DBMS: cambiar el
nombre de la variable por un nombre que empiece
con ‘mnu’, así cuando haya que codificar no es
problemático saber de qué se trata. El modificador
de la variable además es mejor que sea private
(valor por omisión)
text indica el rótulo o label que aparecerá
en el ítem de menú.
Menmonic: la tecla
presionar el usuario
toolTipText:
usuario
ayuda
rápica
que
contextual
podrá
para
el
Agregar el Driver JDBC al Proyecto
au
ra
Una vez que tenemos las clases
bases y el menú no tenemos que
olvidarnos que la aplicación va a
conectarse a una base de datos.
Para ello deberemos abrir la
ventana
propiedades
del
proyecto y buscar la opción
librerías: allí tendremos que
agregar el DRIVER JDBC del
DBMS que vayamos a utilizar.
Pr
of
.L
En mi caso, he elegido MySQL, y
ciertamente el Driver JDBC viene
incluido en el paquete Java. Si
hubiera elegido SQLServer tengo
que bajar el Driver JDBC desde
Microsoft y descargarlo en una
carpeta del equipo. En este caso
hay que seleccionar la 3ª opción:
Add JAR/Folder
Si
se
consulta
ahora
la
estructura del Proyecto, en
Libraries figurará el Driver que
hayamos elegido.
Tenemos la librería pero todavía no podemos conectarnos a la Base de Datos ya que tenemos que contar
con clases que puedan vincular las clases base o las clases gestionadotas de la aplicación con las clases
gestionadotas de la conexión.
El API JDBC – parte 2 pág. 12/20
16. POO APLICADA A BASES DE DATOS
Las clases base que se comunican con el API JDBC
y
Hemos creado otro paquete ‘core’ dentro del Proyecto para alojar a las clases gestionadotas del API
JDBC, de modo tal que el alumno no tenga que complicarse demasiado con este tema.
ttr
La imagen muestra toda la estructura del proyecto hasta ahora:
Las clases de este paquete son dos:
Conectar.java
us
san
Creo que los nombres dicen todo: la clase
Conectar es la clase base para poder establecer
la conexión con el DBM, la clase UsarConexion,
utiliza justamente la conexión para poder
realizar actualizaciones en la base de datos y
consultas. Por ello esta última clase se puede
considerar una clase gestionadota de la
conexión.
Le
UsarConexion.java
Para los prácticos deberán agregar este paquete a sus proyectos, de modo tal de poder establecer la
conexión con el DBMS y poder gestionarlo.
A continuación se lista el código de estas dos clases.
Archivo Conectar.java
Pr
of
.L
au
ra
No
1 package toi_mapeo.core;
2
3 import java.awt.HeadlessException;
4 import java.sql.Connection;
5 import java.sql.DriverManager;
6 import java.sql.SQLException;
7 import javax.swing.JOptionPane;
8
9 /**
10 *
11 * @author Laura Noussan Lettry
12 */
13 public class Conectar {
14 //atributos con los que vamos a crear un objeto Connection
15 private static Connection conn=null;//variable que maneja la conexion
Primer try que
16
controla la existencia
17 //constructor
del Driver; es decir
18 public Conectar(String driver, String cadena, String usuario, String clave){
que exista la clase
19
//primero setear el Driver
que llama al
20
//pero tenemos que usar excepciones, no hay otra
controlador
21
try{
22
String controlador = new String(driver);
23
Class.forName(controlador).newInstance();
24
//si ya tenemos el controlador instanciado podemos crear la conexión
Segundo try que
25
try{
controla el
26
conn=DriverManager.getConnection(cadena,usuario,clave);
establecimiento de la
27
JOptionPane.showMessageDialog(null,"Conectado!!","Información",1 ) ;
conexión con el
28
DBMS
29
}//fin try por conexion ya establecido el driver
30
catch (SQLException | HeadlessException e){
31
String mensajeExcepcion="Error al realizar la Conexión: n"+
32
e.getMessage()+
33
"nLocalización: "+
34
e.getLocalizedMessage();
35
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
36
}
37
}//fin try por Driver
38
catch(ClassNotFoundException | InstantiationException | IllegalAccessException e){
39
String mensajeExcepcion="Error al cargar el controlador: n"+
40
e.getMessage()+
41
"nLocalización: "+
El API JDBC – parte 2 pág. 13/20
17. POO APLICADA A BASES DE DATOS
e.getLocalizedMessage();
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
Le
ttr
y
}
}//fin constructor
public void Desconectar(){
try {
Método para desconectarse.
if(conn != null){
Primero chequea que esté
conn.close();
establecida la conexión.
String mensaje="Desconectado!!";
También va encerrado en un
JOptionPane.showMessageDialog(null,mensaje,"Información",1 ) ;
bloque try-catch.
}//fin if
}//fin try
catch (SQLException | HeadlessException e){
String mensajeExcepcion="Error al Desconectar: n"+
e.getMessage()+
"nLocalización: "+
e.getLocalizedMessage();
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepciñon !!",1 ) ;
}//fin catch
}//fin método Desconectar()
public static Connection getConexion(){
return Conectar.conn;
}
¿Cómo conectarnos al DBMS?
us
san
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 }
au
ra
Activamos el evento (también se
puede lograr haciendo doble ckick
sobre Conetar)
No
Tenemos que activar el evento ActionPerformed del Menú Item Conectar y una vez creada la entrada en
el código agregar las variables y datos necesarios para poder establecer la conexión:
.L
Vemos que el runtime tiene que
importar a la clase Conectar, que
está en el otro paquete.
Pr
of
La variable MySQL es un atributo
necesario, representa la conexión
al nivel del la aplicación
El API JDBC – parte 2 pág. 14/20
18. POO APLICADA A BASES DE DATOS
us
san
Le
ttr
y
Aquí hemos escrito el código necesario para poder establecer el driver y la conexión. Es similar a lo que
hacíamos con el BrowserSQL. Este código se activará cuando el usuario presione el botón Conectar del
menú DBMS.
A este nivel, que estamos en el nivel superior y de gestión de la aplicación, no se ha utilizado ningún
bloque try-catch, porque no es necesario. El control de excepciones está en la clase base del paquete
CORE.
au
ra
No
También debemos escribir el código necesario, previa activación del evento ActionPerformed, para el ítem
Desconectar, que es bien simple: mysql.Desconectar();
.L
Estructura simple de una aplicación que sólo tiene como objetivo que el usuario pueda consultar la
base de datos.
Pr
of
A continuación vamos a mostrar las diferentes pantallas que muestra esta aplicación al interactuar con
el usuario.
El API JDBC – parte 2 pág. 15/20
19. POO APLICADA A BASES DE DATOS
ttr
y
Se lanza la excepción
de la conexión. La del
Driver no se activó
¿por
qué?
Pues
porque yo me olvidé
de colocar bien mi
contraseña
en
el
código.
Ahora
sí
conectamos!
nos
Ahora nos hemos
desconectado del
DBMS!
Pr
of
.L
au
ra
No
us
san
Le
El mensaje en inglés
es bien claro, y es
similar al mensaje
que
enviaría
el
BrowserSQL.
El API JDBC – parte 2 pág. 16/20
20. POO APLICADA A BASES DE DATOS
Una Consulta a la Tabla Alumnos
No
us
san
Le
ttr
A continuación mostraremos el código del evento ActionPerformed de Consultar/Alumnos
y
Una consulta a cualquiera de las tablas no sólo necesita la conexión sino que también requiere que se
utilice, al nivel de la aplicación la clase UsarConexion.java.
En este tipo de consultas, donde hemos escrito una cadena, que no depende de datos ingresados por el
no necesitamos utilizar las clases base de las tablas. En el caso de que la consulta estuviese
parametrizada por valores ingresados por el usuario sí sería necesario primero crear el objeto,
generalmente consultas que impliquen una proyección, una restricción o ambas.
ra
También es necesario utilizar las clases base de las tablas en el caso de las ABM, ya que conviene pasar
en muchos casos objetos, completos; de allí la importancia de tener más de un constructor, uno de ellos
que permita crear un objeto encapsulado (ver el código fuente de las clases base).
au
El evento mnuAlumnosActionPerformed lo primero que hace es chequear que el usuario esté
conectado. Como antes, la excepción se maneja al nivel de las clases base de la conexión; es decir las
clases que interactúan con el API JDBC.
Si el usuario está conectado se puede realizar la consulta, de lo contrario se le avisa al usuario que debe
conectarse.
.L
Para acceder a la base de datos se ha utilizado la variable consulta que es además del tipo
UsarConexion.
También podemos ver que necesitamos un arreglo y una cadena; el arreglo traerá los nombres de los
atributos o columnas de las tablas y la cadena los datos todas las filas con los valores que tienen para
cada atributo..
Pr
of
Se invoca el método Consultar pasándole la cadena de la consulta. Dicho método pertenece a la clase
UsarConexion y permite enviar al API la consulta. Para poder entender este código hay que estudiar la
clase UsarConexion.
Lo que tiene que quedar claro es que la complejidad de establecer la conexión así como el manejo de los
datos y la comunicación con el API JDBC está programado en las clases bases de la conexión y no al nivel
lógico de la aplicación. Justamente, para eso sirve separar la vista de negocio de la vista de aplicación.
Este código que hemos descripto corresponde a la vista de aplicación, mientras que el código fuente del
paquete CORE corresponde a la vista del negocio así como las clases bases de las tablas, que en este
caso, y sólo por el tipo de consulta, no hemos utilizado.
El API JDBC – parte 2 pág. 17/20
21. POO APLICADA A BASES DE DATOS
y
El resultado de la consulta se muestra mediante un JOptionPane, que en su lista de argumentos llama a
un método que hemos escrito especialmente: mostrarConsulta(String [] tit, String dat). Este método
es un método del Jframe, es decir, es un método de la vista de aplicación para separar el c.
ttr
A continuación listamos el archivo UsarConexion.java. Cabe aclarar que esta clase también gestiona las
ABM a nivel del API JDBC pero este tema es de la Unidad 3.
Le
Archivo UsarConexion.java
Pr
of
.L
au
ra
No
us
san
1 package toi_mapeo.core;
2
3 import java.sql.Connection;
4 import java.sql.SQLException;
5 import java.sql.ResultSet;
6 import java.sql.Statement;
7 import java.util.logging.Level;
8 import java.util.logging.Logger;
9 import javax.swing.JOptionPane;
10
11 /**
12 *
13 * @author Laura Noussan Lettry
14 */
15 public class UsarConexion {
16 Connection miConexion;
17 Statement sentencia=null;
18 ResultSet resultado;
19
20 public UsarConexion(Connection c){
21
this.miConexion=c;
22
23 }
24 public void ABM(String cadena){
25
try {
26
sentencia = miConexion.createStatement();
27
sentencia.executeUpdate(cadena);
28
if(miConexion.getAutoCommit()!=true)
29
miConexion.commit();
30
} catch (SQLException ex) {
31
String mensajeExcepcion="Error al realizar la ABM: n"+
32
ex.getMessage()+
33
"nLocalización: "+
34
ex.getLocalizedMessage();
35
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepciñon !!",1 ) ;
36
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
37
}
38
39 }
40 public void Consultar(String cadena){
41
try {
42
sentencia = miConexion.createStatement();
43
sentencia.executeQuery(cadena);
44
resultado = sentencia.getResultSet();
45
46
} catch (SQLException ex) {
47
String mensajeExcepcion="Error al realizar la Consulta: n"+
48
ex.getMessage()+
49
"nLocalización: "+
50
ex.getLocalizedMessage();
51
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
52
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
53
}
54
55
56 }//fin Consultar
57 public int getCantidadColumnasTabla(){
El API JDBC – parte 2 pág. 18/20
22. }
public String getNombreColumnaTabla(int columna){
String nombre="";
try {
nombre=resultado.getMetaData().getColumnName(columna);
ttr
Le
int cantCols=0;
try {
cantCols=resultado.getMetaData().getColumnCount();
} catch (SQLException ex) {
String mensajeExcepcion="Error al devolver la cantidad de columnas: n"+
ex.getMessage()+
"nLocalización: "+
ex.getLocalizedMessage();
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
}
return cantCols;
ra
No
us
san
} catch (SQLException ex) {
String mensajeExcepcion="Error al devolver el nombre de la columna: n"+
ex.getMessage()+
"nLocalización: "+
ex.getLocalizedMessage();
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
}
return nombre;
}
public int getTamanioColumnaTabla(int columna){
int cantidad=0;
try {
cantidad=resultado.getMetaData().getColumnDisplaySize(columna);
} catch (SQLException ex) {
String mensajeExcepcion="Error al devolver el tamaño de la columna: n"+
ex.getMessage()+
"nLocalización: "+
ex.getLocalizedMessage();
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
}
return cantidad;
}
.L
au
public String[] getObtenerNombresColumnas(){
String nomCols[];
int i=0;
int cantCols = this.getCantidadColumnasTabla();
nomCols=new String[cantCols];
for(i=0;i<cantCols;i++){
nomCols[i]=new StringBuilder(this.getTamanioColumnaTabla(i+1)).toString();
nomCols[i]=this.getNombreColumnaTabla(i+1)+" | ";
}
return nomCols;
}//fin getObtenerNombresColumnas
public String getObtenerDatos(){
String datos="";
try {
int i;
int cantCols = this.getCantidadColumnasTabla();
Pr
of
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
y
POO APLICADA A BASES DE DATOS
while (resultado.next()){//el recodrset es una fila con 'n' columnas
String fila="";
for(i=0;i<cantCols;i++){
//el contenido o valor de cada atributo
fila+=resultado.getString(i+1)+" | ";
}//los datos de un registro
datos+="n"+fila;
El API JDBC – parte 2 pág. 19/20
23. ttr
No
us
san
Le
127
}//fin while
128
129
} catch (SQLException ex) {
130
String mensajeExcepcion="Error al leer los datos del RecordSet: n"+
131
ex.getMessage()+
132
"nLocalización: "+
133
ex.getLocalizedMessage();
134
JOptionPane.showMessageDialog(null,mensajeExcepcion,"Excepción !!",1 ) ;
135
Logger.getLogger(UsarConexion.class.getName()).log(Level.SEVERE, null, ex);
136
}
137
return datos;
138 }//fin getObtenerDatos
139
140
141 }
y
POO APLICADA A BASES DE DATOS
La figura muestra el resultado de ejecutar la consulta sobre la tabla Alumnos.
Pr
of
.L
au
ra
El programador puede mejorar el código siempre, por ejemplo colocar en el título del JOptionPane:
Resultado de la consulta efectuada sobre la tabla Alumnos.
El API JDBC – parte 2 pág. 20/20