martes, 19 de junio de 2007

API de Persistencia en NetBeans 5.5

El artículo que traduje "Usando el API de persistencia en aplicaciones de escritorio (Introducción)" ahora pasará a la práctica usando NetBeans 5.5

Pues comenzamos por crear un nuevo proyecto llamado Persistence. Luego, crearemos la unidad de persistencia entrando a New | File dentro de la categoría Persistence.

Definiremos el nombre de la unidad de persistencia (por omisión usaremos el nombre propuesto: PersistencePU). Recordemos que es una buena práctica utilizar el mismo nombre de la base de datos, aunque no necesariamente tengan que ser los nombres. Para la conexión de base de datos, crearemos uno nuevo:

Podemos usar cualquier base de datos. Naturalmente debemos contar con el driver para el JDBC. Yo utilizaré el Firebird, por tanto los valores de la conexión a la base de datos son como sigue:

Ahora vemos que creó el archivo persistence.xml dentro de META-INF, además ya tiene los valores de la plantilla como se mencionó en el artículo:




Ahora, entraremos a New | File para crear una clase Entidad.


Para seguir con las clases mencionadas en el artículo, crearemos la clase Player:




A la clase creada, le agregamos las siguientes líneas
    private String  lastName;
private String firstName;
private int jerseyNumber;
@Transient
private String lastSpokenWords;

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public int getJerseyNumber() {
return jerseyNumber;
}

public void setJerseyNumber(int jerseyNumber) {
this.jerseyNumber = jerseyNumber;
}
public String getLastSpokenWords() {
return lastSpokenWords;
}

public void setLastSpokenWords(String lastSpokenWords) {
this.lastSpokenWords = lastSpokenWords;
}
Podemos agregar mas anotaciones como se mencionó en el artículo.
Crearemos también la clase entidad Team y agregamos los siguientes campos
    private String teamName;
private String division;
private Collection<Player> players;

Lo interesante es este punto es que Netbeans encuentra la referencia con la clase Player, y nos propone hacer una asociación muchos-a-uno o uno-a-muchos:
Así que seleccionaremos la opción bidireccional uno-a-muchos. Al hacer esto, el NetBeans no dirá que creará un nuevo campo para la relación en la base de datos, y la propiedad respectiva en la clase Player.

Podemos crear los campos de la clase y dejar que el Netbeans cree los métodos set & get de ellos. Entramos a Refactor | Encapsulated fields...


Ahora, usaremos la persistencia. Para ello crearemos una clase Main que tendrá el método main(). Luego hacemos clic derecho sobre el código y seleccionamos Persistence | Use Entity Manager


Y vemos que crea una propiedad estática que accede a la unidad de persistencia:

private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersistencePU");

Además, nos muestra un ejemplo de cómo acceder a la persistencia.
Por tanto, haremos un simple ejemplo de guardar en la base de datos:
    private void guardar() {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
Team[] teams =new Team[] {
new Team("Los Angeles Dodgers", "National"),
new Team("San Francisco Giants", "National"),
new Team("Anaheim Angels", "American"),
new Team("Boston Red Sox", "American")
};

Player[] players = new Player[] {
// name, number, last quoted statement
new Player("Lowe", "Derek", 23, "The sinker's been good to me."),
new Player("Kent", "Jeff", 12, "I wish I could run faster."),
new Player("Garciaparra", "Nomar", 5,"No, I'm not superstitious at all.")};

for(Team team: teams) {
em.persist(team);
}


for(Player player:players){
player.setTeam(teams[0]);
teams[0].addPlayer(player);
em.persist(player);
}


em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
}
No olvidar agregar el .jar correspondiente para la base de datos dentro del proyecto.
Ejecutamos el proyecto con F6.. y listo, veamos la base de datos qué registro.



Vemos que también creó una tabla llamada SEQUENCE. Pues bien, como los campos autonuméricos no son estándar en todos los motores de base de datos, el API de persistencia crea una tabla que le permitirá crear un nuevo rango de valores para los campos autonuméricos.

Recuperando registros

¿De qué sirve una solución de persistencia de datos que permita grabar datos si no se pueden recuperar?

El API de persistencia de Java permite obtener registros a través del id del registro:
Player p=em.find(Player.class,55L);
Team t=em.find(Team.class,52L);

... u obtener una lista
Query query=em.createQuery("select c from Player c");
List<Player> lista=query.getResultList();


... y qué mejor que una lista filtrada
Query query=em.createQuery("select c from Player c where c.team.id=51");
List<Player> lista=query.getResultList();
Hay mucho que revisar en la documentación de Java respecto al API de persistencia. Así que ya no hay excusas para reducir el código de acceso a la base de datos.

Recursos

Aquí está el proyecto ejemplo que usé.