OBJETIVOS 1. EXPLICAR QUE ES JPA 2. USAR JPA EN UNA APLICACIÓN 3. GENERAR UNA INTERFACE VISUAL USANDO EL JPA ELBORADO Plataformas Plataformas : Netbeans (7.3.1, Oracle (11g xe) , JDBC, JPA,SWING CONTENNIDO
Mapeo Objeto Relacional ORM “El mapeo objeto-relacional (más conocido por su nombre en inglés, Object-Relational mapping, o sus siglas O/RM, ORM, y O/R mapping) es una técnica de
programación para convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y la utilización de una base de datos relacional, utilizando un motor de persistencia. En la práctica esto crea una base de datos orientada a objetos virtual, sobre la base de datos relacional. Esto posibilita el uso de las características propias de la orientación a objetos (básicamente herencia y polimorfismo). Hay paquetes comerciales y de uso libre disponibles que desarrollan el mapeo relacional de objetos, aunque algunos programadores prefieren crear sus propias herramientas ORM “ Tomado de : http://es.wikipedia.org/wiki/Mapeo_objeto-relacional
Imagen tomada de : http://soyprogramador.liz.mx/wp-content/uploads/2011/11/ORM_thumb.jpg http://soyprogramador.liz.mx/wp-content/uploads/2011/11/ORM_thumb.jpg
El problema Mucha de la Programación realizada con lenguajes Orientados a Objetos en Aplicaciones (Software) que usa bases de datos (que de paso debo decir , son casi todas las aplicaciones que intenten solucionar problemas de las organizaciones y sus sistemas de información) , tiene que ver con la lógica de A) B) C) D)
Crear la bases de datos Gestionar la información de la base de datos (adiciones, modificaciones, retiros y consultas) Crear el modelo de Objetos (clases) en el programa Realizar la equivalencia o correspondencia entre Objetos y entidades (tablas de la base de datos) Lo cual se debe realizar en dos sentidos y momentos : Cuando la información se extrae de la base de datos y se carga en los programas (objetos/clases (objetos/cl ases en consultas) Cuando la información se recibe de los usuarios (mediantes interfaces graficas probablemente) se Convierte en Objetos y se desea llevar a la base de datos (adiciones, modificaciones, borrados)
Esto en todas las aplicaciones son tareas casi similares o muy iguales realizadas realizad as por muchos programadores o por incluso un solo Programador cuando realiza varias aplicaciones. Por o tanto esta tarea se puede estandarizar y realizar en f orma genérica por Programas que se llama ORM ‘s (Mapeadores Objeto Relacionales)
JPA es uno de ellos y es la versión de Java (SUN/ORACLE) basado en Eclipse Link
Imagen tomada de : http://soyprogramador.liz.mx/wp-content/uploads/2011/11/ORM_thumb.jpg http://soyprogramador.liz.mx/wp-content/uploads/2011/11/ORM_thumb.jpg
El problema Mucha de la Programación realizada con lenguajes Orientados a Objetos en Aplicaciones (Software) que usa bases de datos (que de paso debo decir , son casi todas las aplicaciones que intenten solucionar problemas de las organizaciones y sus sistemas de información) , tiene que ver con la lógica de A) B) C) D)
Crear la bases de datos Gestionar la información de la base de datos (adiciones, modificaciones, retiros y consultas) Crear el modelo de Objetos (clases) en el programa Realizar la equivalencia o correspondencia entre Objetos y entidades (tablas de la base de datos) Lo cual se debe realizar en dos sentidos y momentos : Cuando la información se extrae de la base de datos y se carga en los programas (objetos/clases (objetos/cl ases en consultas) Cuando la información se recibe de los usuarios (mediantes interfaces graficas probablemente) se Convierte en Objetos y se desea llevar a la base de datos (adiciones, modificaciones, borrados)
Esto en todas las aplicaciones son tareas casi similares o muy iguales realizadas realizad as por muchos programadores o por incluso un solo Programador cuando realiza varias aplicaciones. Por o tanto esta tarea se puede estandarizar y realizar en f orma genérica por Programas que se llama ORM ‘s (Mapeadores Objeto Relacionales)
JPA es uno de ellos y es la versión de Java (SUN/ORACLE) basado en Eclipse Link
El resultado de usar JAP es lograr este Mapeo y toda la transaccionalidad con las bases de datos en forma rápida lo cual agiliza el desarrollo de software. Algo muy importante de mencionar es que esto es independiente del Gestor de bases de datos (DBMS: ORACLE, MYSL, SQL SERVER, POSTGRESS POSTGRE SS SQL etc.) siempre que sea relacional.
Imagen tomada de : http://i.stack.imgur.com/4sVPQ.png
Otras ventajas de usar este mapeo es: un nivel mas de abstracción de la base de datos, reutilización, seguridad y un lenguaje propio para realizar consultas ya que los Mapeadores traen instrucciones tipo SQL para ello (JQL) y algunas desventajas : se debe estudiar (toma tiempo) y puede ser menos rápido (puede afectar el rendimiento/”performance”) rendimiento/”performance”) Una herramienta ORM muy conocida es Hibernate para java (NHibernate para .NET) Sitios donde puede encontrar mas información Son http://es.wikipedia.org/wiki/Mapeo_objeto-relacional http://www.slideshare.net/inspirateunaula/mapeo-de-objeto-relacional http://www.davidmarco.es/blog/entrada.php?id=144 y este que es para profundizar mas en esta tecnología http://www.javahispano.org/portada/2011/8/1/manual-avanzado-de-jpa-por-carmelo-navarro.html
LA BASE DE DATOS SE GENERA ESTE MODE LO SENCILLO DE UN CAMPEONATO DE FUTBOLL
EL SCRIP SQL RESPECTIVO ESTA EN LE ANEXO1 Y allí se explica como crear crear las tablas en ORACLE ANEXO 3
Inicie Netbeans Cree una carpeta (windows) en el disco C llámela Proyectos y luego en Netbeans Cree un nuevo proyecto
Un proyecto Java Application Llámelo PROCAMPEONATO y seleccione la ubicación (Project Location)
CREE TRES PACKAGES
MODELO VISTA CONTROL
En control crearemos los Objetos (clases para la Persistencia JPA) En MODELO Crearemos las Entity CLasses Y en vista haremos al final la interface visual GUI (Graphical User Interface) Ahora crearemos las entity clases ,
Presione botón derecho sobre el package MODELO/new y seleccione Entity CLasses from dataBase como se Muestra
Aparece esta ventana
INCLUIR EL DRIVER ORACLE THIN : ojdbc6.jar ojdbc14.jar o classes12.jar depende de la versión de Oracle usada) Debe primero colocar el driver en directorio accesible al proyecto Yo lo coloco en CONTROL (carpeta /package) el driver es ojdbc6.jar Búsquelo en el directorio donde tiene instalado Oracle (versiones 10G en adelante) si no lo tiene Bájelo de internet ojdbc14.jar (usare el ojdbc6.jar)
Se coloca como dije en el directorio CONTROL (package) Luego adiciónelo al proyecto con (presione botón derecho sobre libraries) y seleccione Add JAR/Folder
Se debe crear la conexión a la base de datos (Database Connection) aquí crearemos una nueva Si ya esta creada simplemente la selecciona de la lista despelgable Seleccione new database connection
Elija Driver: ORACLE thin Y presione le botón next
Ahora especifique los datos
Y se especifican los parametros
localhost 1521 XE user y password (en mi caso dbuser y dbuser respectivamente)
ELIJA EL DRIVER CREADO
Espere a que cargue todas las tablas de ese Usuario (mi caso dbuser) Y busco la tabla Partido
La paso al lado derecho (selected tables) y el me incluye las dos realcionadas con Partido que son: Equipo y Campeonato) Presiono next Aparece esta y presiono next
Debe haber generado
Cada entity class con su respectivo código
Presione botón derecho sobre el PACKAGE CONTROL
Y pase las tres para el lado derecho
Presione next y finish
El Proyecto Luce Asi:
Y ha creado CampeonatoJpaController , EquipoJpaController, partidoJpaController Cada una con Créate , edit , destroy , varios métodos find y get
Haremos un programa simple de prueba por consola Para ello mire el archivo persisntence.xml
Copie el nombre la unidad de persistencia jpa creada
PROCAMPEONATOPU
Para ello cree un main con este código public static void main(String[] a) throws Exception { public static void main(String[] a) throws Exception { EntityManagerFactory emf = Persistence.createEntityManagerFactory("PROCAMPEONATOPU"); EntityManager em = emf.createEntityManager(); EquipoJpaController service = new EquipoJpaController (emf); em.getTransaction().begin(); Equipo equi=new Equipo(); equi.setNombreequipo("MEDELLIN"); equi.setCiudad("MEDELLIN"); Short x=0; equi.setNropuntos(x); equi.setNropartidosjugados(x); equi.setNropartidosganados(x); equi.setNropartidosempatados(x); equi.setNropartidosperdidos(x); service.create(equi); em.getTransaction().commit();
System.out.println("SE HA GRABADO " + equi); em.close(); emf.close();} Lo ejecuta y El resultado en la salida es
Seleccione los datos en oracel y era un nuevo equipo
Puede usar este otro main public static void main(String[] a) throws Exception { EntityManagerFactory emf = Persistence.createEntityManagerFactory("PROCAMPEONATOPU"); EntityManager em = emf.createEntityManager(); EquipoJpaController service = new EquipoJpaController (emf); em.getTransaction().begin(); List lequi=null; lequi = service.findEquipoEntities(); if(lequi.size()>0){
System.out.println("TRAJO :" + lequi.size()+ " EQUIPOS"); for (Iterator iteratorE = lequi.iterator(); iteratorE.hasNext();) { Equipo equi = (Equipo) iteratorE.next(); System.out.println(equi); } } em.close(); emf.close(); }
Y la salida será esta
FUNCIONA!!! Ahora a hacer la Interface para poner esto a funcionar mejor (con interface gráfica GUI)
PARA HACER LAS ADICIONES, MODIFICACIONES, BORRADO Y CONSULTA DE LA BASE DE DATO
Cree un Jframe PartidosGUI con este diseño
Lo que se desea es (ver la interface) cargar el combo box que esta la final de la Ventana con la información de los equipos(nombres) Cuando el programa se inicie
Cree esta clase en el pakage CONTROL import MODELO.Equipo; import java.util.Iterator; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;
public class transEquipo { EntityManagerFactory emf; EntityManager em ; EquipoJpaController service; public transEquipo(){ iniciar(); } public void iniciar(){ emf = Persistence.createEntityManagerFactory("PROCAMPEONATOPU"); em = emf.createEntityManager(); service = new EquipoJpaController (emf); } public List traerEquipos(){ List lequi=null; em.getTransaction().begin();
lequi = service.findEquipoEntities(); if(lequi.size()>0){ for (Iterator iteratorE = lequi.iterator(); iteratorE.hasNext();) { Equipo equi = (Equipo) iteratorE.next(); } } return lequi; } public void llenarCB(javax.swing.JComboBox jcb){ List lequi=null; em.getTransaction().begin();
lequi = service.findEquipoEntities(); if(lequi.size()>0){ System.out.println("TRAJO :" + lequi.size()+ " EQUIPOS"); for (Iterator iteratorE = lequi.iterator(); iteratorE.hasNext();) { Equipo equi = (Equipo) iteratorE.next(); jcb.addItem(equi.getNombreequipo()); } } } public void cerrar(){ em.close(); emf.close(); } }
Muy bien ahora coloque este código en la ventana que creo A) Incluya como una porpiedad de la Ventana transEquipo trequipo; y debajo de InitCompoenentes este código trequipo = new transEquipo(); trequipo.llenarCB(jComboBox1); Y ejecute para ver la ventana Deberá ver esto
Y el comboBox esta cargado con los Nombres de los equipos
Ahora incluiremos la lógica para cargar la información de un partido Recuerde que la llave de partidos esta dada por el nombre del Equipo Local y el nombre del equipo Visitante JPA crea una class Partido PK con los dos String (local Y visitante) que forman la llave en la Tabla Partido.
Cree esta clase transPartido. import import import import import
MODELO.Partido; MODELO.PartidoPK; javax.persistence.EntityManager; javax.persistence.EntityManagerFactory; javax.persistence.Persistence;
public class transPartido { EntityManagerFactory emf; EntityManager em ; PartidoJpaController service; public transPartido(){ emf = Persistence.createEntityManagerFactory("PROCAMPEONATOPU"); em = emf.createEntityManager(); service = new PartidoJpaController (emf); } public Partido getPartido(String EquipoLocal,String EquipoVisitante) { Partido p=null; em.getTransaction().begin(); System.out.println("Consultando PARTIDO POR LLAVE.."); PartidoPK id = new PartidoPK();
id.setLocal(EquipoLocal); id.setVisitante( EquipoVisitante);
try {
p = service.findPartido(id); System.out.println("local: " + p.getEquipo(). getNombreequipo()) ; System.out.println("visitante: " + p.getEquipo1().getNombreequipo()); System.out.println("campeonato: " + p.getNombrecampeonato()); return p; } catch (Exception e) { e.printStackTrace(); return p; } finally { em.close(); emf.close(); } } }
Tiene algunos Println , déjelos mientras prueba y quítelos cuando todo este funcionado en la interface (GUI) Para incluir la lógica que trae los datos de un partido , llamando al método public Partido getPartido(String EquipoLocal,String EquipoVisitante) de esta clase que acaba de crear vaya a la interface GUI (PartidosGUI) y dele doble click al botón buscar e inserte el código para crear una clase transPartido y traer un partido con los dos datos que introduzca el usuario en los campos nombre del equipo local y nombre del equipo visitante Luego los datos se muebve ala ventana con el método moveralaVentana(p);
transPartido tp=new transPartido(); String local=""; String visitante=""; local =jTextField1.getText(); visitante = jTextField2.getText(); Partido p= tp.getPartido(local, visitante); if(p!=null){ moveralaVentana(p); } else{ javax.swing.JOptionPane.showMessageDialog(this, "NO EXISTE ESTE PARTIDO"); }
El método moveralaVentana(p); quedaria asi (solo se mueve el nombre del campeonato para probar que funciona public void moveralaVentana(Partido p){ jLabel4.setText(p.getNombrecampeonato().getNombrecampeonato()); }
Se mostrará solo el nombre del campeonato que es lo único que estamos moviendo a la ventana
Pero agreguemos la otra información y procedamos a hacer cambios (una nueva función) para actualizar los marcadores de los partidos (goles del ocal y goles de los visitantes) para que vean como funciona traer la información (consultas)
Haga este cambio en la base de datos
Y cambie el método mover a la ventana por este public void moveralaVentana(Partido p){ jLabel4.setText(p.getNombrecampeonato().getNombrecampeonato()); jTextField3.setText(p.getNrogoleslocal()+""); jTextField4.setText(p.getNrogolesvisitante()+""); }
Ejecute de nuevo y digite CALI AMERICA en local y visitante respectivamente. Debe salir así:
Puede quitar los Println que muestran datos por consola para dejar el programa sin este ruido.
Para ello cree este método en transPartido. public boolean InsertarPartido(Partido p){ boolean r=true; em.getTransaction().begin(); try{ service.create(p); }catch(PreexistingEntityException e){ r=false; } catch( Exception e){ r=false; } return r; }
Y en la interface Visual PartidosGUI en el Boton add digite este código Partido p=new Partido(); Short golesLocal=0; Short golesVisi=0; String local=jTextField1.getText(); String visitante= jTextField2.getText(); Equipo A = new Equipo(); Equipo B = new Equipo(); A.setNombreequipo(local); B.setNombreequipo(visitante); p.setEquipo(B); p.setEquipo1(A); Campeonato c= new Campeonato(); c.setNombrecampeonato("COPA BAVARIA"); p.setNombrecampeonato(c);
golesLocal= Short.parseShort(jTextField3.getText()); golesVisi= Short.parseShort(jTextField4.getText()); p.setNrogoleslocal(golesLocal); p.setNrogolesvisitante(golesVisi); transPartido tp=new transPartido(); if(tp.InsertarPartido(p)) javax.swing.JOptionPane.showMessageDialog(this,"PARTIDO INSERTADO EXITOSAMENTE"); else javax.swing.JOptionPane.showMessageDialog(this,"NO SE PUDO INSERTAR /n Probablemente ya existe");
OBSERVE QUE : El Euipo1 de partido definido por JPA es el local y el Visitante Equipo. (en MODELO.Partido)
Mire que faltan partidos
Por ejemplo NACIONAL -CALI probemos insertar este definale un marcador O NACIONAL- MILLOS Presione add y luego trate de consultarlo (borre por ejemplo el marcador) DIGITE en local NACIONAL y en visitante CALI Deberá traer sus datos . POR HACER: intente hacer el código del Boton Mod y del Boton Del Para lo de Pdf le recomiendo la Iblreria IText y para los archivos Excel la librería jXLS Disfruta la programación ESTO ES TODO.
ANEXO 1 CREATE TABLE CAMPEONATO ( NOMBRECAMPEONATO VARCHAR2(40) NOT NULL, CONSTRAINT PK_CAMPEONATO PRIMARY KEY (NOMBRECAMPEONATO) ) /
CREATE TABLE EQUIPO ( NOMBREEQUIPO VARCHAR2(30) NOT NULL, CIUDAD VARCHAR2(40) NOT NULL, NROPUNTOS NUMBER(4) NOT NULL, NROPARTIDOSJUGADOS NUMBER(4) NOT NULL, NROPARTIDOSGANADOS NUMBER(4) NOT NULL, NROPARTIDOSEMPATADOS NUMBER(4) NOT NULL, NROPARTIDOSPERDIDOS NUMBER(4) NOT NULL, CONSTRAINT PK_EQUIPO PRIMARY KEY (NOMBREEQUIPO) ) /
CREATE TABLE JUGADOR ( CEDULA NUMBER(12) NOT NULL,
APELLIDOJUGADOR VARCHAR2(40) NOT NULL, NOMBREJUGADOR VARCHAR2(40) NOT NULL, NROCAMISETA NUMBER(2) NOT NULL, VALORPASE NUMBER(12) NOT NULL, NOMBREEQUIPO VARCHAR2(30) NOT NULL, CONSTRAINT PK_JUGADOR PRIMARY KEY (CEDULA) ) /
CREATE TABLE PARTIDO ( LOCAL VARCHAR2(30) NOT NULL, VISITANTE VARCHAR2(30) NOT NULL, NROGOLESLOCAL NUMBER(2) NOT NULL, NROGOLESVISITANTE NUMBER(2) NOT NULL, NOMBRECAMPEONATO VARCHAR2(40) NOT NULL, CONSTRAINT PK_PARTIDO PRIMARY KEY (LOCAL, VISITANTE) ) /
ALTER TABLE JUGADOR ADD CONSTRAINT FK_JUGADOR_EQUIPO
FOREIGN KEY (NOMBREEQUIPO) REFERENCES EQUIPO (NOMBREEQUIPO) /
ALTER TABLE PARTIDO ADD CONSTRAINT EQUIPO_local FOREIGN KEY (LOCAL) REFERENCES EQUIPO (NOMBREEQUIPO) /
ALTER TABLE PARTIDO ADD CONSTRAINT EQUIPO_visitante FOREIGN KEY (VISITANTE) REFERENCES EQUIPO (NOMBREEQUIPO) /
ALTER TABLE PARTIDO ADD CONSTRAINT FK_PARTIDO_CAMPEONATO FOREIGN KEY (NOMBRECAMPEONATO) REFERENCES CAMPEONATO (NOMBRECAMPEONATO) /
ANEXO 2 DROP (BORRADO DE TABLAS)
ALTER TABLE JUGADOR DROP CONSTRAINT FK_JUGADOR_EQUIPO /
ALTER TABLE PARTIDO DROP CONSTRAINT EQUIPO_local /
ALTER TABLE PARTIDO DROP CONSTRAINT EQUIPO_visitante /
ALTER TABLE PARTIDO DROP CONSTRAINT FK_PARTIDO_CAMPEONATO /
DROP TABLE CAMPEONATO CASCADE CONSTRAINTS /
DROP TABLE EQUIPO CASCADE CONSTRAINTS /
DROP TABLE JUGADOR CASCADE CONSTRAINTS /
DROP TABLE PARTIDO CASCADE CONSTRAINTS /
ANEXO 3 INSERT DE LOS DATOS
INSERT INTO EQUIPO VALUES('CALI','CALI',0,0,0,0,0); INSERT INTO EQUIPO VALUES('AMERICA','CALI',0,0,0,0,0); INSERT INTO EQUIPO VALUES('MILLOS','BOGOTA',0,0,0,0,0); INSERT INTO EQUIPO VALUES('NACIONAL','MEDELLIN',0,0,0,0,0); INSERT INTO JUGADOR VALUES(10,'RODRIGUEZ','JAMES',10,300000,'CALI'); INSERT INTO JUGADOR VALUES(11,'SANCHEZ','DIEGO',10,300000,'CALI');
INSERT INTO JUGADOR VALUES(12,'RAMIREZ','DARIO',10,300000,'AMERICA'); INSERT INTO JUGADOR VALUES(13,'PEREZ','HERNANDO',10,300000,'AMERICA'); INSERT INTO JUGADOR VALUES(14,'ARIAS','LUIS',10,300000,'NACIONAL'); INSERT INTO JUGADOR VALUES(15,'UMAÑA','PEDRO',10,300000,'NACIONAL'); INSERT INTO JUGADOR VALUES(16,'MARADONA','PABLO',10,300000,'MILLOS'); INSERT INTO CAMPEONATO VALUES('COPA BAVARIA'); INSERT INTO PARTIDO VALUES('CALI','AMERICA',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('AMERICA','CALI',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('MILLOS','CALI',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('CALI','MILLOS',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('MILLOS','AMERICA',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('AMERICA','MILLOS',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('NACIONAL','AMERICA',0,0,'COPA BAVARIA'); INSERT INTO PARTIDO VALUES('AMERICA','NACIONAL',0,0,'COPA BAVARIA');
ANEXO 4 COMO CREAR LAS TABLAS Paso 1: cree en el disco c una carpeta A (c:/A) Paso 2 : ENTRE A ORACLE connect código/password o como ustede se conecta habitualemente Paso 3 : cree el archivo creac.SQL
Copie el script allí
Salvelo (salgase de boloc de notas de oracle) y ejecútelo Con