Richiamare il DataBase, JPA e JavaBeans

Vediamo come richiamare il DB SQL utilizzando Java. Col DB ci parlo tramite MYSQL un software ma come fa Java a parlare con MYSQL?

MYSQL è un processo in esecuzione all’interno del sistema operativo e che resta in attesa di chiamate ad una certa porta. Vedi articolo dedicato.

In questo articolo vediamo come funziona la nostra applicazione Java che costruisce le query senza doverlo fare direttamente noi.

dbms

JDBC

la soluzione più facile è utilizzare JDBC (Java DataBase Connector), una serie di classi che permettono di comunicare col DB.

Fa parte del JAVA SE. Come ad esempio le collections sono una serie di classi che rispondono al problema di usare le strutture dati, invece  le JDBC rispondono alla necessità di parlare col DB che è un processo che vive fuori in maniera indipendente dal nostro programma Java.

 

 

DB JAVA

 

Lo svantaggio è che c’è molto codice che si troverebbe in mezzo al codice del nostro model, il quale risulterebbe poco immediato e leggibile.

JPA

Un livello sopra JDBC che si può utilizzare è il framework JPA (Java Persistence API) che comunque internamente utilizza JDBC, ma noi scriviamo codice JPA. Fa parte della JAVA EE. L’idea di JPA è utilizzare delle annotazioni nelle classi per dire che le classi corrispondo a delle tabelle.

  • fornisce una mappatura tra classi Java e tabelle del database
  • fornisce un linguaggio per effettuare query SQL, chiamato JPQL (Java Persistence Query Language), che è indipendente dalla DBMS utilizzato
  • fornisce varie API per la gestione e manipolazioni degli oggetti Java che mappano le tabelle del database.

Vediamo la sintassi del codice per la classe ad esempio UserEntity :

@Entity
@Table(name = "USERS")
public class UserEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long id;
    private String name;
    private String surname;
    private String code;

    @OneToMany(mappedBy = "userEntity")
    private Set cars;

    @OneToOne(mappedBy = "userEntity", cascade = CascadeType.ALL, orphanRemoval = true)
    @PrimaryKeyJoinColumn
    private ContactEntity contactEntity;

    public void addCar(CarEntity carEntity) {
        carEntity.setUserEntity(this);
        if(this.cars == null) {
            this.cars = new HashSet<>();
        }
        this.cars.add(carEntity);
    }
    
    public void removeCar(CarEntity carEntity) {
        this.cars.remove(carEntity);
        carEntity.setUserEntity(null);
    }
    //getters, setters, equals, hashcode
}

 

  • Con @Entity stiamo indicando a JPA che questa classe Java mappa una tabella del database.

 

  • Con @Table(name = “USERS”) indichiamo a JPA il nome della tabella mappata. Se non scriviamo l’ annotazione, viene creata una tabella con lo stesso nome della classe Java.

 

  • Con @Id indichiamo che il campo annotato è una primary key.

 

  • Con @GeneratedValue(strategy = GenerationType.IDENTITY) indichiamo che l’id è una IDENTITY (cioè è un campo che viene auto-incrementato dal DBMS).

 

  • Con @Column(name = “user_id”), indichiamo a JPA che questo campo Java mappa la colonna user_id. Se non scriviamo l’ annotazione, JPA mappa una colonna con lo stesso nome del campo Java.

 

  • Con @OneToMany(mappedBy = “userEntity”) stiamo dicendo a JPA che questa tabella è in relazione 1:M con la classe CarEntity che mappa la tabella CARS. Inoltre, con mappedBy indichiamo a JPA che CarEntity ha un attributo chiamato userEntity per mappare la relazione inversa M:1.

 

  • Con @OneToOne(mappedBy = “userEntity”) indichiamo che esiste una relazione 1:1 con la classe ContactEntity che mappa la tabella CONTACTS.

 

  • Con @PrimaryKeyJoinColumn, indichiamo a JPA che la tabella CONTACTS ha come chiave primaria la stessa della tabella USERS.

 

Per approfondimenti vedi articolo dalla fonte: https://www.vincenzoracca.com/blog/framework/jpa/jpa-reletions/

 

I JavaBeans (EJB)

(Per approfondimenti vedi wikipedia)

Utilizzare i JavaBeans non vuol dire altro che scrivere una classe Java Serializzabile con certe regole che facilitino l’inserimento degli oggetti nel DataBase. Sono utilizzati per incapsulare più oggetti in un oggetto singolo il Bean.

Le convenzioni richieste sono:

  • La classe deve avere un costruttore senza argomenti
  • Presenta i metodi get, set, is e altri metodi cosiddetti metodi accessori
  • La classe dovrebbe essere Serializzabile (capace di salvare e ripristinare il suo stato in modo persistente)
  • Non dovrebbe contenere alcun metodo richiesto per la gestione degli eventi

I diversi tipi di Beans

Una caratteristica dei Beans è la persistenza. Significa che li possiamo salvare in un DB Sql. La serializzazione infatti in parole povere serve a trasformare un oggetto in formato binario, come un insieme di bit. Il Bean che viene salvato in SQL si chiama Entity  è un entity bean. Ogni Entità è una tabella SQL.

Ci sono 4 tipi di Beans :

  • Il Bean di entità che serve per salvare i dati in SQL.
  • Il Bean Singleton Session può avere una sola istanza nell’application server. Essendo classi possono avere varie istanze solitamente.
  • Il Bean Stateful Session salvano lo stato tra una chiamata e l’altra.
  • Il Bean Stateless Session gestisce il Bean di entità che è poi l’interfaccia dati.

 

Nell’esempio sotto diciamo che la classe Person è una entità (@Entity). Il campo private long id è identificativo (@Id)  generato automaticamente (@GeneratedValue(strategy=GenerationType.AUTO)) questo codice infatti manda avanti automaticamente il contatore id ogni volta che viene creata una nuova riga nel DB.

Ciò che interpreta tutto questo è un provider JPA  come Hibernate o EclipseLink che trasforma la nostra @Entity in una tabella nel DB. 

Le Entity poi vengono gestite dai Beans Session (Stateless, Stateful o Singleton).

CREARE JAVABEANS ENTITY:

// Questo tag indica a eclipseLink di creare una tabella da questa classe
@Entity
//se non indico table name, mi crea automaticamente la tabella con nome della classe
@Table(name = "PEOPLE")

@NamedQueries({ @NamedQuery(name = "PersonENT.findAll", query = "SELECT p FROM UserENT p"),
  @NamedQuery(name = "PersonENT.findById", query = "SELECT p FROM UserENT p WHERE p.id = :id"),
})


public class PersonENT implements Serializable {
	private static final long serialVersionUID = 1L;
	   
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
 	

	public PersonENT() {
		super();
	}   
	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}

 

CREARE JAVABEANS SESSION STATELESS:

E nell’altro Session Bean Stateless invece gestisco l’Entità con i vari metodi per leggere, modificare, salvare, rimuovere.

/**
 * Session Bean implementation class personaBean
 */
@Stateless
@LocalBean
public class PersonEJB {

//impostare prima su application server il contesto di persistenza e indicarlo		 
@PersistenceContext(unitName = "mainJPU")
private EntityManager em;
 
    public PersonEJB() {
        // Default constructor 
    }

// ********************************************************
// Quando devo leggere tutte le righe della tabella richiamo le query dell'entità

   @SuppressWarnings("unchecked")
   public List getPersonList() {

      List list;

      Query persENTQuery = em.createNamedQuery("PersonENT.findAll", PersonENT.class);

      list = persQuery.getResultList();

      return list;
    }
    
     /** OPERAZIONI GET, CREATE, MERGE, REFRESH, DETACH, REMOVE **/

  	public PersonENT getPerson(Long id) {

  		return em.find(PersonENT.class, id);
  	}

  	public void personaPersist(PersonENT ord) {
  		em.persist(p);
  	}

  	public PersonENT personMerge(PersonENT p) {
  		return em.merge(p);
  	}

  	public void personRefresh(PersonENT p) {
  		em.refresh(p);
  	}

  	public void personDetach(PersonENT p) {
  		em.detach(p);
  	}

  	public void personRemove(PersonENT item) {

  		if (item.getId() != null) {

  			item = em.merge(item);
  			em.remove(item);

  		} else {
  			System.out.println("[WARN] personRemove: void ID entity!");
  		}

  	}
}


Richiamare/caricare i Beans di sessione per essere usati

I Beans vivono all’interno dell’application Server, per usarli dobbiamo agganciarli facendo un dispatcher:

package nome.package.test

public class EJBDispatcher {

	public static final String EJBS_BASEPATH="java:global/PercorsoMiaApplicazione/cartellaEJB/";
	
	public EJBDispatcher() {
	}

public static TestEJB getTestEJB() {

		TestEJB myTestEJB = null;

		try {

			InitialContext ic = new InitialContext();
			myTestEJB = (TestEJB) ic
					.lookup(EJBS_BASEPATH + "TestEJB!nome.package.test.TestEJB");

		} catch (NamingException e) {

			e.printStackTrace();
		}

		return myTestEJB;
	}


In Conclusione

Una volta che ho le classi modellate come Bean (es. classe Utente) posso associarla a un DB ma questo verrà fatto utilizzando codice JPA che permette di indicare quali sono identificare le colonne del DB con le annotazioni e poi utilizzando del codice Eclipselink che salvarà questi oggetti nel DB utilizzando queste informazioni.

Un pensiero su “Richiamare il DataBase, JPA e JavaBeans

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *