Java, java REST web service (api) con connessione a database mySql schema Biblioteca.
-
Si propone un semplice esempio di web service REST su uno schema Biblioteca, ove si registrano le letture (prestiti) di libri a un certo numero di utenti.
Le tabelle (entità) dello schema saranno quindi anagrafica (utenti), libri e letture (associazione N:M tra utenti e libri).
Per rendere il database utilizzabile secondo il paradigma REST ogni tabella ha un proprio ID numerico, sono inoltre inseriti dei vincoli di univocità.
Schema DB
-
Con NetBeans la creazione del web service è fatto dal wizard della IDE,
si può selezionare il database e di seguito le tabelle.
Si suggerisce di creare l'applicazione web facendo riferimento al server GlassFish anziché Tomcat.
Verranno create le classi Java Anagrafica, Libri e Letture.
Nella classe Anagrafica, vengono già create delle query su tutti i campi della tabella,
si può inserire una query aggiuntiva per la ricerca tramite nome e cognome.
@NamedQuery(name = "Anagrafica.findByNomeCognome", query = "SELECT a FROM Anagrafica a WHERE a.nome = :nome AND a.cognome = :cognome")
-
Per poter utilizzare la query aggiunta con un metodo del web service è quindi necessario
aggiornare la classe AnagraficaFacadeREST.
In questo caso si aggiunge un metodo con proprio nome e si passano due path params (due parametri sul path URL).
La richiesta sarà quindi del tipo:
Request: GET http://localhost:8080/APIBiblioteca/webresources/anagrafica/ricerca/mario/rossi
@Path("ricerca/{nome}/{cognome}")
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Anagrafica> ricerca(@PathParam("nome") String nome, @PathParam("cognome") String cognome) {
return (List<Anagrafica>) em.createNamedQuery("Anagrafica.findByNomeCognome").setParameter("nome", nome).setParameter("cognome", cognome).getResultList();
}
-
Per poter utilizzare la query findByNome, che non ha un metodo già pronto, è necessario
aggiornare la classe AnagraficaFacadeREST.
In questo caso si aggiunge un metodo con proprio nome e si passa un path params.
La richiesta sarà quindi del tipo:
Request: GET http://localhost:8080/APIBiblioteca/webresources/anagrafica/ricercapernome/mario
@Path("ricercapernome/{nome}")
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Anagrafica> ricercapernome(@PathParam("nome") String nome) {
return (List<Anagrafica>) em.createNamedQuery("Anagrafica.findByNome").setParameter("nome", nome).getResultList();
}
-
Se invece vogliamo avere l'elenco di tutti i libri letti da un utente
dobbiamo fare una join tra tabelle, possiamo quindi aggiungere un metodo alla classe
LettureFacadeREST.
In questo caso si aggiunge un metodo con proprio nome e si passa un path params, in questo caso l'id dell'utente.
La query è fatta direttamente nel metodo tramite l'oggetto query.
Si faccia attenzione alla query, nella condizione l.idanagrafica.id = :idutente
idanagrafica non è l'ID dell'utente come nella tabella del database ma l'oggetto Anagrafica,
si veda infatti come è stata costruita la classe Letture.
La richiesta sarà quindi del tipo:
Request: GET http://localhost:8080/APIBiblioteca/webresources/letture/ricercaperidutente/7
@Path("ricercaperidutente/{id}")
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Letture> ricercaperidutente(@PathParam("id") Integer id) {
Query query = em.createQuery("SELECT l FROM Letture l WHERE l.idanagrafica.id = :idutente");
query.setParameter("idutente", id);
List<Letture> lista = query.getResultList();
return lista;
}
-
Se invece vogliamo avere l'elenco di tutti i libri letti da un utente, ricercandolo però per nome e cognome,
dobbiamo fare una join tra tabelle, possiamo quindi aggiungere un metodo alla classe
LettureFacadeREST.
In questo caso si aggiunge un metodo con proprio nome e si passano due query params - tanto per cambiare e per vedere la differenza -
che saranno il nome e il cognome dell'utente.
La query è fatta direttamente nel metodo tramite l'oggetto query.
Si faccia attenzione alla query, nella condizione a.id = l.idanagrafica.id
idanagrafica non è l'ID dell'utente come nella tabella del database ma l'oggetto Anagrafica,
si veda infatti come è stata costruita la classe Letture.
La richiesta sarà quindi del tipo:
Request: GET http://localhost:8080/APIBiblioteca/webresources/letture/ricercaperidutente?nome=mario&cognome=rossi
Si noti il modo diverso di lavorare del QueryParam dal precedente PathParam.
@Path("ricercaperidutente")
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Letture> ricercaperidutente(@QueryParam("nome") String nome, @QueryParam("cognome") String cognome) {
Query query = em.createQuery("SELECT l FROM Anagrafica a, Letture l WHERE a.nome = :nome AND a.cognome = :cognome AND a.id = l.idanagrafica.id");
query.setParameter("nome", nome);
query.setParameter("cognome", cognome);
List<Letture> lista = query.getResultList();
return lista;
}