Hibernate esempio hello world Dott. Doria Mauro doriamauro@gmail.com
Presentiamo un primo esempio che consente di gestire un messaggio di testo. Lo scopo è quello di storare il messaggio hello world sul db per poi recuperarlo e quindi modificarlo. 2
Si crea un nuovo progetto Java stand-alone. 3 Le librerie di base da importare sono: asm.jar log4j.jar cglib.jar commons-collections.jar commons-logging.jar dom4j.jar hibernate3.jar mysql-connector-java-5.1.7-bin (per MySQL) jta.jar
Il file xml di configurazione 4 Il file di configurazione generale si presenta in questa forma: <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <! Configura connessione e dialetto --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/helloworld</property> <property name="hibernate.connection.username >root</property> <property name="hibernate.dialect">org.hibernate.dialect.mysql5dialect</property> <! Stampa SQL sulla console--> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="use_sql_comments">true</property> <!-- Lista dei file xml di mapping--> <mapping resource="hello/message.hbm.xml"/> </session-factory> </hibernate-configuration>
Consideriamo la seguente classe: package hello; public class Message { private Long id; private String text; private Message nextmessage; private Message() { Identificativo univoco Messaggio di testo Riferimento al succ. messaggio 5 public Message(String text) { this.text = text; public Long getid() { return id; private void setid(long id) { this.id = id; public String gettext() { return text; public void settext(string text) { this.text = text; public Message getnextmessage() { return nextmessage; public void setnextmessage(message nextmessage) { this.nextmessage = nextmessage;
Cosa notiamo dalla classe precedente? La classe Message segue le specifiche java-beans:. La classe Message possidere i metodi get/set e un costruttore a zero parametri. La classe Message non fa nessun riferimento al framework Hibernate, pertanto è un POJO (Esattamente il contrario degli EJB 2.1 il cui codice si può utilizzare solo sulla piattaforma EJB). 6 La classe Message possiede una attributo speciale che identifica gli oggetti come univoci al pari di una chiave primaria: se due oggetti hanno valori diversi per l attributo id, allora corrisponderanno a due righe diverse sul DB.
Scriviamo una classe di prova per storare un messaggio con Hibernate: public class ProvaWrite { public static void main(string args[]) { SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory(); Session session =sessionfactory.getcurrentsession(); Transaction newtransaction = session.begintransaction(); Message message = new Message("Hello World"); session.save(message); newtransaction.commit(); sessionfactory.close(); Interfaccia Session e Transaction di Hibernate 7 L esecuzione produrrà del codice SQL simile a questo: insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (1, 'Hello World', null) Notare il progressivo
Scriviamo una classe di prova per recuperare messaggi con Hibernate: Public classe ProvaWrite { public static void main(string args[]) {. session = sessionfactory.getcurrentsession(); Transaction newtransaction = session.begintransaction(); List messages = session.createquery("from Message as m order by m.text asc").list(); System.out.println( messages.size() + " messaggio(i) trovato(i) " ); for ( Iterator iter = messages.iterator(); iter.hasnext(); ) { Message message = (Message) iter.next(); System.out.println( message.gettext() ); newtransaction.commit(); sessionfactory.close(); Hibernate query 8 select m.message_id, m.message_text, m.next_message_id from MESSAGES m order by m.message_text asc
Scriviamo il XML mapping document: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernatemapping-3.0.dtd"> <hibernate-mapping> <class name="hello.message" table="messages"> <id name="id" column="message_id"> <generator class="increment"/> </id> Mapping campo text <property name="text" column="message_text"/> <many-to-one name="nextmessage" cascade="all" column="next_message_id"/> </class> </hibernate-mapping> Classe Message Tabella Messages Associazione self molti-a-uno 9 Mapping campo id chiave primaria Autoincremento chiave
10 Scriviamo una classe di prova per gestire con Hibernate un oggetto messaggio. In particolare vogliamo recuperare il testo associato al primo messaggio, sostituirlo con un altro e inserire il messaggio successivo al primo: Public classe ProvaWrite { public static void main(string args[]) {. session = sessionfactory.getcurrentsession(); newtransaction = session.begintransaction(); // 1 è l'id del primo messaggio message = (Message) session.get( Message.class, new Long(1) ); message.settext("funziona veramente!"); Message nextmessage = new Message("questo è un secondo messaggio"); message.setnextmessage( nextmessage ); newtransaction.commit(); sessionfactory.close(); Sostituzione testo messaggio Aggiunta messaggio successivo
Il codice SQL autogenerato da Hibernate sarà simile a questo: select m.message_id, m.message_text, m.next_message_id from MESSAGES m where m.message_id = 1 Recupero primo messaggio insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (2, 'Take me to your leader (please)', null) Inserimento nuovo messaggio con MESSAGE_ID progressivo Modifica testo primo messaggio Relazione molti-a-uno con il primo messaggio 11 update MESSAGES set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2 where MESSAGE_ID = 1
In questo piccolo esempio possiamo notare alcune caratteristiche di Hibernate: automatic dirty checking: Update automatico del DB a fronte di chiamate ai metodi set sull oggetto cascading save: Persistenza automatica di un oggetto collegato ad un altro che si trova già nello stato di persistenza (non è necessario chiamare il metodo save() sull oggetto collegato) transactional write-behind: autodeterminazione del miglior ordine con cui eseguire le istruzioni SQL senza violare i vincoli sulle chiavi esterne (vincoli di integrità referenziale) 12 NOTA: l ordine con cui sono fatte le operazioni Java non è uguale all ordine con cui vengono eseguite le istruzioni SQL
Domande? 13 :