|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
[JAVA/DB file-based] Implementazione di un'applicazione che utilizza un DB.
Come da titolo, vorrei fare un programmino semplicissimo che utilizza un database file-based (il database è presente su un file che può essere copiato e scarrozzato ovunque).
Detto questo ho un problema serio di implementazione dovuto alle mie scarse esperienze nella programmazione JAVA-DB {con PHP/MySQL risolverei in 30minuti}. Ho un database con una semplice tabella contenente degli acquisti (per ora) e devo richiamare le informazioni sul programma, ma come faccio? IPOTESI 1: Creare una classe 'acquisto' avente come variabili private i campi della tabella e i relativi metodi setVariabile()/getVariabile() per poterle modificare. Poi per caricare il database dovrei creare tante istanze { new Acquisto() } quante sono le righe della tabella? IPOTESI 2: Anche con JAVA è possibile leggere e scrivere sul database 'seduta stante', quindi basterebbero delle funzioni statiche e dei link agli ID {stile Browser} ? Putroppo non ho mai visto del codice di un programma che utilizzasse un DB quindi non so proprio come fare.. Non ho ancora scritto nemmeno una riga di codice perchè prima voglio farmi uno schema di quello che andrò a fare (visto che dovrò preparare anche l'interfaccia). Poi se qualcuno conosce un programmino opensource che fa più o meno la stessa cosa mi piacerebbe esaminarlo, il miglior modo è sempre quello..
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV Ultima modifica di LacioDromBuonViaggio : 27-04-2009 alle 11:36. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Entrambe le ipotesi sono realistiche, nel senso che si può fare l'uno e l'altro. Il "come" varia a seconda della tecnologia che si vuole usare. Esistono framework di persistenza come hibernate, esistono le API persistence che si appoggiano a framework di persistenza e c'è il package sql nudo e crudo.
La scelta può dipendere dall'esistenza o meno di un supporto JDBC per il database da usare. Che database usi? |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Quote:
Io vorrei fare una semplice interfaccia con dei campi di testo che una volta compilati vengano inseriti tramite query nel database e viceversa: caricare da database un elenco di 'acquisti' e poterci cliccare sopra in modo da vederne i dettagli. Tutto qua, ma non ho la più pallida idea di come poterlo implementare attraverso la programmazione orientata agli oggetti: che classi utilizzo, per fare che cosa? {Forse essendo troppo abituato a PHP/MySQL non riesco a vedere la cosa da un punto di vista diverso}
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
H2 supporta le api J2EE persistence. Bene.
Tutorial superespresso alle JPA. set-up Scarichi le librerie toplink essentials. https://glassfish.dev.java.net/downl...rsistence.html Una volta che hai queste librerie quello che puoi fare è fregartene di connessioni e disconessioni e query e lavorare direttamente in Java. Funziona come nella tua ipotesi 1. Crei una classe che aggrega i dati che infileresti in una riga di una tabella (o in più tabelle correlate, è irrilevante). Diciamo che, esempio tipico, il dato aggregato è una persona e che le persone hanno un nome. La rappresentazione di questo dato in Java con l'uso della api persistence è: Codice:
import javax.persistence.*;
@Entity
public class Persona {
@Id
private int id;
private String name;
public int getId() { return id; }
public String getName() { return name; }
public void setId(int id) { this.id = id; }
public void setName(String name) { this.name = name; }
@Override public int hashCode() { return id; }
@Override public boolean equals(Object that) {
return that instanceof Persona ? ((Persona)that).id == id : false;
}
}
Il database è rappresentato da un oggetto di tipo EntityManager. Ottieni un EntityManager con le seguenti istruzioni: import javax.persistence.*; ...a un certo punto... EntityManagerFactory factory = Persistence.createEntityManagerFactory("NOME"); EntityManager database = factory.createEntityManager(); Il nome in grassetto lo vediamo dopo. Con un EntityManager puoi eseguire due tipi di operazioni. Operazioni sulle entità e comandi SQL. Quelle interessanti sono le prime perchè alla fine il tuo database è organizzato e gestito a colpi di oggetti Java. Ad esempio il "salvataggio" di una persona ipotetica: Persona p = new Persona(); p.setId(1); p.setNome("Pippo"); si esegue con: database.getTransaction().begin(); database.persist(p); database.getTransaction().commit(); Puoi recuperare una persona conoscendone l'id: Persona p = database.getReference(Persona.class, 1); Puoi eseguire query SQL usando createNativeQuery(String) o eseguire query JSQL con createQuery. Le seconde restituiscono oggetti Java. Ad esempio una uqery JSQL per ottenere tutte le persone nel database sarebbe: Codice:
Query q = database.createQuer("SELECT p FROM Persona p");
for(Object o : q.getResultList()) {
Persona risultato = (Persona)o;
}
Il nome in grassetto. La connessione con la base dati è gestita autonomamente dalle API persistence basandosi sul contenuto di un file properties.xml. Questo file deve essere contenuto in una directory di nome META-INF accessibile dal classpath (in pratica nella stessa cartella da cui esegui il programma o nella cartella META-INF del file jar se l'applicazione è impacchettata). Il file persistece.xml contiene la definizione degli attributi necessari a creare delle unità di persistenza. L'unità di persistenza è quella roba che va a cercare il metodo Persistence.createEntityManagerFactory("NOME"); e "NOME" è appunto il nome dell'unità come dichiarato nel file persistence.xml. Un esempio di file persistence.xml che permette la gestione di oggetti Persona su un database h2 con le api TopLink è questo: Codice:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="PersonaService" transaction-type="RESOURCE_LOCAL">
<class>Persona</class>
<properties>
<property name="toplink.jdbc.driver" value="org.h2.Driver"/>
<property name="toplink.jdbc.url" value="jdbc:h2:prova"/>
<property name="toplink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
</persistence>
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PersonaService"); L'altra riga in grassetto è "class". Nel nodo che dichiara un'unità di persistenza occorre dichiarare il nome pienamente qualificato (cioè nomepackage.NomeClass) delle entità gestite dall'unità di persistenza. Noi abbiamo una sola entità, Persona, quindi abbiamo un solo nodo class. L'ultima parte in evidenza è la stringa di connessione al database. La stringa dipende dal database, per H2 dire "jdbc:h2: prova" significa che si tratta di un database embedded di nome "prova" collocato nella directory di lavoro. Fine del tutorial su JPA più breve mai realizzato |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Ma quante ne sai?
Credo sia proprio quello di cui ho bisogno! Piuttosto, se volessi dare il tutto a un niubbo ancora più niubbo di me potrei metterglielo in una cartella con qualche file e un JAR dicendogli: "toh, esegui il JAR" ? L'importante è che inserisca nel JAR tutte le librerie essenziali? Oppure l'importante è che siano nella cartella? Vorrei evitare installazioni di librerie, modifica di classpath e sbattimenti vari che non siano di installare (ovviamente) la JVM classica.. ![]() Domandina ricapitolativa: ma quindi quale sarebbe la differenza tra H2 e le JPA? Altra domandina: oltre a JDK, H2 e JPA mi serve qualcos'altro?
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV Ultima modifica di LacioDromBuonViaggio : 27-04-2009 alle 17:19. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
La struttura tipica di un'applicazione java desktop non richiede alcun intervento dell'utente salvo scaricare uno zip che contiene il programma e fare doppio click sul jar che c'è nella cartella creata dalla decompressione di quello zip. Di solito ha questa "faccia":
[programma]/Programma.jar [programma]/librerienative.dll [programma]/lib/unjar.jar [programma]/lib/unaltrojar.jar [programma]/lib/eccetera.jar Il collegamento tra Programma.jar e i jar che stanno in lib avviene tramite un attributo del file Manifest usato dal jar. Si usa l'attributo Class-Path del manifesto, che potrebbe avere questa forma: Codice:
Manifest-Version: 1.0 Main-Class: quel che è Class-Path: lib/toplink-essentials-agent.jar lib/toplink-essentials.jar lib/h2-1.1.111.jar Alla fine ti trovi quindi con un jar, quello del tuo programma, e una cartella lib che contiene gli altri quattro jar. Niente classpath o altre diavolerie. Volendo potresti anche fondere i quattro jar in un unico jar e avere solo il tuo Programma.jar. Si tratta di file zip, non è un gran problema, basta solo "fondere" i file Manifest.mf che trovi nelle cartelle META-INF di ogni file jar in un unico Manifest da usare poi per il tuo jar. |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
In tutto ti servono 3 librerie, toplink-essentials.jar, toplink-essentials-agent.jar e h2-1.1.111.jar, più il file persistence.xml da mettere nella cartella META-INF del jar del tuo programma.
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Ottimo, spero di non fare casini {cosa molto probabile}! Tanto inizio con programmini 'giocattolo' di prova..
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Domandina veloce.
Sto scaricando JAVA EE 5 SDK da qui {il terzo}. Le JPA saranno incluse nel pacchetto, o dovrò scaricarle a parte?
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Sono incluse ma non so dove siano (se in j2ee.jar o da qualche altra parte. Propendo per l'altra parte).
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Ho dei problemi nel capire come funziona l'accesso al database.
Per poter accedere al database ho bisogno di user e password, ma questi dati chi li decide e quando? L'utente utilizzatore non dev'essere informato di questi dati, il programma seleziona il database (file creato e modificato in precedenza dallo stesso programma) e lo apre. {Questo è quello che serve a me. } Poi ho visto qualche esempio di user e password salvati nel database, ma in questo caso penso ci si riferisca a programmi multi-utenti, con vari gradi di accesso e privilegi. {E non mi interessa}
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Solitamente username e password sono gestiti dal modulo di autenticazione del sistema che è controllato dall'amministratore del sistema (cioè dall'utente che ha i privilegi di amministrazione).
Il modulo contiene un elenco protetto di nomi utente con relative password. Il modulo accetta delle richieste di autenticazione. Significa che io persona qualsiasi posso richiedere al modulo tramite una connessione non autenticata di garantirmi l'accesso agli altri moduli dell'applicazione. Per farlo fornisco al modulo le mie credenziali (nome utente e password). Il modulo di autenticazione le verifica e se l'esito della verifica è positivo mette a mia disposizione il resto dei servizi del programma. Tutto 'sto giro richiede l'esistenza di una "configurazione iniziale" vale a dire che deve esserci almeno un nome utente ed una password preimpostata - solitamente quella di amministrazione che è introdotta nel sistema dal programma che installa il software. Detto questo la domanda che mi sorge è: stai realizzando un'applicazione in cui esiste un sistema di servizi fisicamente separati dal client che li usa oppure è una classica applicazione desktop "all in one"? Perchè nel secondo caso la faccenda è più ostica. Il concetto di autenticazione si basa sull'indisponibilità da parte dell'utente del modulo di autenticazione (e del contenuto a cui questo accede). Se manca questa separazione la storia dei meccanismi di protezione ci dice che il massimo che puoi fare è ostacolare in misura più o meno grave l'accesso dell'utente alle informazioni di autenticazione. In pratica puoi benissimo scrivere nome utente e password direttamente nel codice. |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Quote:
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
esatto.
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Grazie, ma tanto tutti questi vaneggi non credo mi serviranno con le JPA.
Ho un problemino con il persistence.xml. Premetto che la struttura della cartella è: Codice:
Persona.java (uguale alla tua se non che ho inserito il costruttore per velocizzare) GestioneDB.java (inserisce Persone su DB e legge il DB) lib (contenente le 3 librerie) META-INF (contenente il persistence.xml) Codice:
javax.persistence.PersistenceException: No resource files named META-INF/services/javax.persistence.spi.PersistenceProvider were found. Please make sure that the persistence provider jar file is in your classpath. at javax.persistence.Persistence.findAllProviders(Persistence.java:167) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:103) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83) at GestioneDB.<init>(GestioneDB.java:14) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at bluej.runtime.ExecServer$3.run(ExecServer.java:814) Uso BlueJ e affinchè mi vedesse le 3 librerie le ho dovute aggiungere nelle preferenze (altrimenti mi dava errore sull'import), però questa cartella non è una libreria quindi non saprei come aggiungerla. Creando un JAR del progetto ho visto che crea in automatico la cartella META-INF con all'interno il manifest.mf. Quindi come glielo faccio vedere 'sto file .xml? Devo per forza creare il jar ogni volta che voglio fare un test? Oppure ho capito male dove deve andare il file persistence.xml? Oppure non è quello il problema! EDIT -- non mi funziona nemmeno se crea un jar e lo apro da terminale. Ho cercato un pò su google e un tipo che usa NetBeans ha risolto aggiungendo le 2 librerie toplink-essential tramite il comando 'Add Libraries'! Ma io l'avevo già fatto ma non mi funziona lo stesso....
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV Ultima modifica di LacioDromBuonViaggio : 13-05-2009 alle 11:54. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Non è il tuo file persistence che non vede ma il servizio di persistenza di toplink. Questo file qui:
"META-INF/services/javax.persistence.spi.PersistenceProvider" si trova nel file jar toplink-essentials.jar. Direi che è un problema di classpath. Verifica che nel manifest del jar del tuo programma sia specificata l'opzione Class-Path, che qui siano elencate le tre librerie che ti servano e che le stesse siano disponibili al jar (esternamente). |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Quote:
Quindi devo per forza creare il JAR ogni volta che faccio un minimo cambiamento? Non posso copiare 'temporaneamente' le librerie nella classpath--> dove?
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV Ultima modifica di LacioDromBuonViaggio : 13-05-2009 alle 13:45. |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
Dove dipende dall'IDE che usi. Il classpath è una variabile tranquillamente impostabile all'atto dell'esecuzione/compilazione e di solito gli ide ne approfittano a mani basse creando cartelle e cartelline varie in cui uno deve poi immaginare di infilare le proprie librerie.
Ad esempio in Netbeans metteresti la cartella META-INF con dentro il file persistence.xml nella cartella "src" mentre i tre jar andrebbero aggiunti come librerie con l'apposito "click" su libraries. Dopodichè Netbeans si occupa di rendere disponibile l'ambaradam sia al compilatore che alla jvm. Senza IDE, data la strutturazione che hai presentato nel post precedente, diresti semplicemente: java -cp .;lib/* GestioneDB "-cp" sta per "il classpath è", . è la directory di esecuzione, lib/* è la cartella lib che si trova nella directory di esecuzione e l'asterisco sta per "tutti i jar contenuti in". |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Jul 2008
Città: Sardegna
Messaggi: 1005
|
Forse ho fatto qualche passo avanti... forse
Ho creato il jar (togliendo la cartella lib e lasciando esterne le 3 librerie). Ora ho una cartella contenente il jar del programma e le 3 librerie. Il manifest.mf è apposto. Al comando java -jar programma.jar però mi da un errore diverso: Codice:
Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named PersonaService: The following providers:
oracle.toplink.essentials.PersistenceProvider
oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
Returned null to createEntityManagerFactory.
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:154)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
at GestioneDB.<init>(GestioneDB.java:14)
at GestioneDB.main(GestioneDB.java:40)
Oppure manca qualche tag nell'xml?
__________________
Aeroengine II BBA Black | Asus P5N-T Deluxe 780i | Intel E8400 C0 @4,050Ghz 1,35v + TR Ultra-120 eXtreme | Corsair 2x2GB PC6400 XMS2 DHX @900Mhz 2,15v | XFX 8800 GT 512MB @730/990 + TR HR-03 Rev. A | Tagan TG500-BZ | Zalman ZM-MFC2 Fan Control | WD Raptor 10000rpm 150 GB + 1,5TB | Iiyama ProLite E2607WSV Ultima modifica di LacioDromBuonViaggio : 13-05-2009 alle 14:53. |
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
|
il tuo file persistence.xml com'è?
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:18.





















