Hibernate - MAPPING

April 28th, 2009
Comments Off

I mappaggi oggetto/relazione vengono definiti in un documento XML. Il documento di mappaggio è progettato per essere leggibile e modificabile a mano. Il linguaggio di mappaggio è java-centrico, nel senso che i mappaggi sono costruiti intorno alle dichiarazioni delle classi persistenti, non sulle dichiarazioni delle tabelle.

Esistono un certo numero di strumenti per generare il documento di mappaggio, tra cui XDoclet, Middlegen e AndroMDA, ma è anche possibile generare i documenti di mappaggio senza utilizzare nessun strumento specifico, ma utilizzando un semplice editor di testo.

Un esempio di mappaggio definito sull’oggetto precedentemente definito è il seguente:

 
                <!-- qui potrebbe stare il mappaggio per Dog -->

Di seguito verranno descritti solo gli elementi e gli attributi del documento che Hibernate usa in fase di esecuzione. Il documento di mappaggio contiene anche alcuni elementi ed attributi opzionali che hanno effetto sugli schemi del database exportati dallo strumento di generazione dello schema (schemaexport). (Ad esempio l’attributo not-null.)

  • Doctype: indica l’effettivo DTD utilizzato che si trova all’URL indicato, nella directory hibernate-x.x.x/src/net/sf/hibernate del pacchetto di Hibernate o nel file hibernate.jar. Hibernate cercherà sempre per prima cosa il DTD sul classpath.
  • Hibernate-Mapping: questo elemento ha tre attributi opzionali: l’attributo schema specifica che le tabelle a cui si fa riferimento nel mappaggio appartengono allo schema indicato. L’attributo default-cascade che specifica quale stile di cascata dovrebbe essere assunto e l’attributo auto-import che consente di utilizzare nomi di classe non qualificati nel linguaggio di interrogazione come comportamento predefinito.
  • Class: è l’elemento che si utilizza per dichiarare una classe persistente. L’elemento è formato da diversi attributi, che sono: name che indica il nome di classe java completamente qualificato della classe persistente (o l’interfaccia); table che indica il nome della sua tabella di database; discriminator-value (opzionale - il default è il nome della classe) indica un valore che distingue sottoclassi individuali, usato per il comportamento polimorfico.

I valori accettabili includono null e not null; mutable (opzionale, il default è true) specifica che le istanze della classe (non) sono mutabili; schema (opzionale) serve per sovrascrive il nome dello schema specificato dall’elemento radice ; proxy (opzionale) specifica una interfaccia da usare per i mediatori (proxy) ad inizializzazione ritardata; dynamic-update (opzionale, il default è false) specifica che una UPDATE SQL dovrebbe venire generata in fase di esecuzione e contenere solo i nomi delle colonne di cui sono cambiati i valori; dynamic-insert (opzionale, il default è false) specifica che le INSERT SQL dovrebbero venire generate in fase di esecuzione e contenere solo i nomi delle colonne i cui valori sono non nulli; select-before-update (opzionale, il default è false):
specifica che Hibernate non dovrebbe mai eseguire una UPDATE a meno che non sia certo che un oggetto non sia davvero stato modificato.

In certi casi (in realtà solo quando un oggetto transiente sia stato associato ad una nuova sessione usando update()), questo significa che Hibernate effettuerà una istruzione SQL SELECT in più per determinare se UPDATE sia realmente richiesto; where (opzionale) specifica una condizione WHERE dell’SQL arbitraria da usare quando si recuperano oggetti di questa classe; persister (opzionale): specifica un ClassPersister personalizzato; batch-size (opzionale, il default è 1) specifica una “dimensione di blocco” (batch) per il caricamento di istanze di questa classe per identificatore; optimistic-lock (opzionale, il default è version) determina la strategia di locking ottimistico;
lazy (opzionale):
impostare lazy=”true” è una scorciatoia equivalente a specificare il nome stesso della classe come interfaccia proxy;

  • Id: Le classi mappate devono dichiarare la colonna di chiave primaria della tabella sul database. La maggior parte delle classi avrà anche una proprietà nello stile dei javabean (cioè con metodi “getter” e “setter”) che manterrà l’identificatore unico di un’istanza. L’elemento definisce il mappaggio da quella proprietà alla colonna di chiave primaria. Gli attributi dell’elemento sono: name (opzionale) che indica il nome della proprietà identificatore; type (opzionale) che indica il tipo di Hibernate; column (opzionale - il default è il nome della proprietà)che specifica il nome della colonna di chiave primaria; unsaved-value (opzionale - il default è null) che è un valore di proprietà di identificazione che indica che un’istanza è appena stata istanziata (è “unsaved”), distinguendola da istanze che siano state salvate o caricate in una sessione precedente; access (opzionale - il default è property) che specifica la strategia che Hibernate dovrebbe usare per accedere al valore della proprietà. L’elemento figlio obbligatorio indica una classe Java utilizzata per generare identificatori unici per istanze di questa classe persistente. Se l’istanza del generatore richiedesse di essere configurata o inizializzata con dei parametri, questi possono essere passati usando l’elemento generator indica una classe Java utilizzata per generare identificatori unici per istanze di questa classe persistente. Se l’istanza del generatore richiedesse di essere configurata o inizializzata con dei parametri, questi possono essere passati usando l’elemento. Hibernate fornisce un certo numero di implementazioni preinstallate. Ci sono anche dei nomi abbreviati per i generatori preinstallati ad es. increment ( genera identificatori di tipo long, short o int che sono unici solo quando nessun altro processo inserisce dati nella stessa tabella), identity (supporta le colonne “identity” in DB2, MySQL, MS SQL Server, Sybase e HypersonicSQL), sequence (usa una “sequence” in DB2, PostgreSQL, Oracle, l’identificatore restituito è di tipo long, short o int.), hilo (usa un algoritmo hi/lo per generare efficientemente identificatori di tipo long, short o int, date una tabella e una colonna) ecc..

L’algoritmo Hilo

I generatori hilo e seqhilo forniscono due implementazioni alternative dell’algoritmo hi/lo, un approccio importante per la generazione di identificatori. La prima implementazione richiede una tabella “speciale” del database per mantenere il prossimo valore “hi” disponibile. La seconda usa una “sequence” nello stile di Oracle (dove sia supportata).

L’algoritmo UUID

Gli UUIDs contengono: indirizzo IP, tempo di partenza della JVM (accurato al quarto di secondo), il tempo di sistema e il valore di un contatore (unico all’interno della JVM).
Non è possibile ottenere un indirizzo MAC o un indirizzo di memoria da del codice java, quindi questo è il massimo che possiamo fare senza usare JNI.

  • L”elemento version è opzionale, e indica che la tabella contiene dati versionati. È particolarmente utile se progettate di usare transazioni lunghe
  • L’elemento opzionale timestamp indica che la tabella contiene dati con marche di tempo
  • L’elemento property dichiara una proprietà persistente in stile JavaBeans della classe, possiede gli attributi name (nome della proprietà), column (il nome della colonna mappata della tabella del database), type (tipo di Hibernate), insert/update (specifica che le colonne mappate dovrebbero essere incluse in istruzioni SQL UPDATE e/o INSERT),formula (opzionale, indica una espressione SQL che definisce il valore per una proprietà), access (opzionale, indica la strategia che Hibernate deve usare per accedere al valore della proprietà).

Hibernate - Gestione della persistenza

April 28th, 2009
Comments Off

Ora siamo pronti per lanciare l’interfaccia di gestione della persistenza per memorizzare e recuperare istanze della classe Cat sul e dal database. Prima però dobbiamo recuperare un’istanza di Session (che è l’unità di lavoro di Hibernate) dalla SessionFactory tramite

SessionFactory sessionFactory =new Configuration().configure().buildSessionFactory();

La SessionFactory è responsabile per un singolo database, e può usare un file di configurazione solo (hibernate.cfg.xml).
Potete impostare altre proprietà (e anche cambiare i metadati di mappaggio) accedendo all’oggetto Configuration prima di costruire la SessionFactory (è immutabile).
Una SessionFactory viene solitamente costruita una volta sola, ad esempio all’avvio con un servlet impostato con il parametro load-on-startup.
Questo significa anche che non dovreste tenerlo in una variabile di istanza nei vostri sevlet, ma in qualche altra posizione.
Abbiamo bisogno di qualche tipo di Singleton, in modo tale da poter accedere facilmente alla SessionFactory.

Configurazione e accesso ad una SessionFactory

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();

In una Session, ogni operazione sul database avviene in una transazione che isola le operazioni (anche quelle di sola lettura). Usiamo l’API Transaction di Hibernate per astrarre dalla strategia
transazionale sottostante (nel nostro caso, transazioni JDBC). Questo consente di mettere in esecuzione il nostro codice con transazioni gestite dal contenitore senza alcun cambiamento. Notate
che l’esempio sopra non gestisce alcuna eccezione.
Notate anche che potete chiamare HibernateUtil.currentSession(); tutte le volte che volete, e otterrete sempre la Session corrente per il thread. Dovete assicurarvi che la Session venga chiusa
sempre dopo che l’unità di lavoro si completi, o nel servlet o in un servlet filter prima che la risposta HTTP venga inviata.

L’effetto collaterale piacevole di questo approccio è un facile accesso ad un meccanismo di inizializzazione “lazy” (pigro, ovvero che carica i dati solo quando servono): la Session è ancora aperta quando la pagina viene generata, così Hibernate può caricare oggetti non inizializzati quando navigate nel grafo.

Hibernate ha vari metodi che possono essere usati per recuperare oggetti dal database.
Il più flessibile è usare il linguaggio di query di Hibernate(HQL) oppure SQL Standard, che è facile da imparare ed una estensione potente ed orientata agli oggetti dell’SQL:

Transaction tx = session.beginTransaction();
Query query = session.createQuery("select c from Cat as c where c.sex = :sex");
query.setCharacter("sex", 'F');
for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
out.println("Female Cat: " + cat.getName() );
}
tx.commit();

Hibernate offre anche un’API ad oggetti che consente di eseguire in modo semplice ed efficace query per criteri che può essere usata per formulare query “type-safe” (ovvero il cui tipo viene verificato in fase di compilazione).
Hibernate usa naturalmente oggetti Prepared-Statement e binding di parametri per tutte le comunicazioni SQL con il database.
Potete anche usare le funzionalità di interrogazione diretta via SQL di Hibernate, o ricevere una connessione JDBC da una Session.

Hibernate - Mapping della classe creata

April 28th, 2009
Comments Off

 Il file di mappaggio Cat.hbm.xml contiene i metadati richiesti per il mappaggio oggetto-relazione.

I metadati  includono  la  dichiarazione  delle  classi  persistenti  e  il  mappaggio  delle  proprietà  sulle tabelle del database (tramite le colonne e le relazioni con altre entità gestite da chiavi esterne).

<?xml version="1.0"?> 
<!DOCTYPE hibernate-mapping 
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> 
<hibernate-mapping> 
<class name="net.sf.hibernate.examples.quickstart.Cat" table="CAT"> 
<!-- A 32 hex character is our surrogate key. It's automatically 
generated by Hibernate with the UUID pattern. --> 
<id name="id" type="string" unsaved-value="null" > 
<column name="CAT_ID" sql-type="char(32)" not-null="true"/> 
<generator class="uuid.hex"/> 
</id> 
<!-- A cat has to have a name, but it shouldn' be too long. --> 
<property name="name"> 
<column name="NAME" length="16" not-null="true"/> 
</property> 
<property name="sex"/> 
<property name="weight"/> 
</class> 
</hibernate-mapping>

Ogni classe persistente dovrebbe avere un attributo di identificazione (in realtà, solo classi che
rappresentano entità, e non gli oggetti dipendenti, che sono mappati come componenti di un’entità).
Questa proprità viene usata per distinguere oggetti persistenti: due gatti sono uguali se
catA.getId().equals(catB.getId()) è vera: questo concetto è chiamato identità del database.

Tutte le altre proprietà di Cat sono mappate sulla stessa tabella.

La proprietà “name” viene mappata con una colonna del database dichiarata esplicitamente.

Questo è particolarmente utile quando si voglia che lo schema del database venga generato automaticamente (sotto forma di istruzioni SQL DDL) a partire dai file di mappaggio tramite lo strumento di Hibernate SchemaExport.

Tutte le altre proprietà vengono mappate usando le impostazioni predefinite di Hibernate, che è ciò di cui si ha
bisogno la maggior parte delle volte.

La tabella CAT nel database appare così:

Column  | Type | Modifiers
--------+-----------------------+-----------
cat_id  | character(32)         | not null
name    | character varying(16) | not null
sex     | character(1)          |
weight  | real                  |

Dovreste ora creare manualmente la tabella nel database.

Hibernate - La prima classe persistente

April 28th, 2009
Comments Off

Hibernate funziona meglio con il modello degli oggetti POJO per le classi persistenti.

Un POJO è più o meno come un JavaBean, con proprietà accessibili tramite metodi “getter” e “setter” (rispettivamente per recuperare e impostare le proprietà), mascherando la rappresentazione interna tramite l’interfaccia pubblicamente visibile:

public class Cat {
private String id;
private String name;
private char sex;
private float weight;
public Cat() {
}
public String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
 }
}

Per le classi persistenti non è richiesta l’implementazione di alcuna interfaccia particolare, né dobbiamo ereditare da una speciale classe persistente radice.

Hibernate non usa neppure alcun tipo di computazione in fase di “build” (costruzione del software), come manipolazione del codice binario (byte-code): si appoggia esclusivamente su reflection Java e su potenziamento in fase di esecuzione delle classi (tramite CGLIB).

Hibernate - Configurazione

April 28th, 2009
Comments Off

La distribuzione di hibernate include una guida pdf completa e comprensiva. Lo scopo di questo file
è solo quello di dare un aiuto per la configurazione iniziale.

Questa guida mostra come installare e configurare hibernate in un servlet container (Tomcat, Resin,
JRun…) per realizzare un’applicazione web.

Hibernate funziona sia in ambienti gestiti dai principali server J2EE che in applicazioni a sé stanti.

Il sistema di gestione di basi dati (DBMS) utilizzato in questa guida è MySql, ma per utilizzare altri
database è sufficiente sostituire il driver della connessione.

L’ultimo elemento del file hibernate.cfg.xml dichiara Cat.hbm.xml come nome di un
file di mappaggio XML di Hibernate per la classe persistente Cat. Questo file contiene i metadati
per il mappaggio delle classi verso una tabella o più tabelle di database.

Prima di tutto, dobbiamo copiare tutte le librerie richieste nell’installazione di Tomcat. Usiamo un
contesto web separato (webapps/quickstart) per questa introduzione, dobbiamo quindi considerare sia il percorso di ricerca globale delle librerie (TOMCAT/common/lib) sia il classloader al livello del contesto in webapps/quickstart/WEB-INF/lib (per i file JAR) e webapps/quickstart/WEB-INF/classes.

Ci riferiremo ai due livelli di classloader con i termini di “classpath globale” e “classpath di contesto”.

Dopo aver scompattato l’archivio scaricato da http://hibernate.sourceforge.net, copiate le librerie incluse nei due classpath sopraindicati:

  • Il driver JDBC per il database nel classpath globale.
  • Le librerie hibernate2.jar, dom4j.jar, CGLIB.jar, CommonsCollections.jar, CommonsLogging.jar, ODMG4.jar, EHCache.jar nel classpath.

Il prossimo passo è quello di configurare Hibernate usando un pool di connessioni preventivamente creato (per la creazione del pool di connessioni si rimanda alla documentazione SUN).

All’interno del classpath di contesto (webinf/classes) bisogna creare il file di configurazione di hibernate chiamato hibernate.cfg.xml: 

java:comp/env/jdbc/quickstart false
net.sf.hibernate.dialect.MySQLDialect

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration 
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" 
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> 
<hibernate-configuration> 
<session-factory> 
<property name="connection.datasource">java:comp/env/jdbc/quickstart</property> 
<property name="show_sql">false</property> 
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property> 
<!-- Mapping files --> 
<mapping resource="Cat.hbm.xml"/> 
</session-factory> 
</hibernate-configuration>

Il dialetto è un’impostazione necessaria, poiché i database differiscono nella loro interpretazione dello “standard” SQL. Hibernate gestisce le differenze e viene fornito con dialetti per tutti i principali database commerciali e open-source.

La SessionFactory è il concetto che in Hibernate corrisponde ad un contenitore di dati univoco.

Database multipli possono essere usati creando file di configurazione XML multipli e creando più oggetti Configuration e SessionFactory nella vostra applicazione.

Hibernate - Architettura

April 28th, 2009
Comments Off

Una visione (molto) di alto livello sull’architettura di Hibernate:

Lo schema rappresenta il modo con cui Hibernate usa il database e i dati di configurazione per fornire servizi di persistenza (e oggetti persistenti) all’applicazione.

La  flessibilità  di  Hibernate  e  rende  possibili  diversi  approcci,  un  esempio  può  essere  un architettura “leggera” che è quella in cui l’applicazione fornisce le sue connessioni JDBC e gestisce le transazioni utilizzando un sottoinsieme minimale delle API di Hibernate, mentre un  architettura  “completa”,  permette  all’applicazione  di  astrarre  dai  dettagli  delle  API JDBC/JTA e lascia che se ne occupi Hibernate.

Uno dei concetti fondamentali dell’architettura di Hibernate è quello di Classi Persistenti, ovvero  quelle  classi  che  in  un’applicazione  implementano  le  entità  del  problema  di business (ad esempio Customer e Order in una applicazione di e-commerce).

Hibernate funziona meglio se queste classi seguono alcune semplici regole, conosciute anche come il modello di programmazione dei “cari vecchi oggetti java” (in inglese e nel seguito si usa l’acronimo POJO che sta per “Plain Old Java Object”). 

Un esempio di POJO:

import java.util.Set;
import java.util.Date;
 
public class Cat {
    private Long id; // identificatore
    private String name;
    private Date birthdate;
    private Cat mate;
    private Set kittens
    private Color color;
    private char sex;
    private float weight;
 
    private void setId(Long id) {
        this.id=id;
    }
    public Long getId() {
        return id;
    }
 
    void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
 
    void setMate(Cat mate) {
        this.mate = mate;
    }
    public Cat getMate() {
        return mate;
    }
 
    void setBirthdate(Date date) {
        birthdate = date;
    }
    public Date getBirthdate() {
        return birthdate;
    }
    void setWeight(float weight) {
        this.weight = weight;
    }
    public float getWeight() {
        return weight;
    }
 
    public Color getColor() {
        return color;
    }
    void setColor(Color color) {
        this.color = color;
    }
    void setKittens(Set kittens) {
        this.kittens = kittens;
    }
    public Set getKittens() {
        return kittens;
    }
    // addKitten non è richiesto da Hibernate
    public void addKitten(Cat kitten) {
        kittens.add(kitten);
    }
    void setSex(char sex) {
        this.sex=sex;
    }
    public char getSex() {
        return sex;
    }
}

Hibernate - Introduzione

April 28th, 2009
Comments Off

Hibernate  è  uno  dei  più  noti  framework  Java  per  l’Object  Relational  Mapping  che semplifica  e  automatizza  la  gestione  della  corrispondenza  tra  il  modello  ad  oggetti  delle nostre  applicazioni  e  quello  relazionale  dei  database  server  ai  quali  queste  ultime comunemente  si  interfacciano. 

In  pratica  uno  o  più  file  di  configurazione  stabiliscono  la corrispondenza tra gli oggetti della nostra applicazione e le tabelle del db.

Hibenate  si  pone  tra  il  modello  ad  oggetti  che  si  ricava  dalla  logica  della  nostra applicazione  e  l’insieme  delle  tabelle,  chiavi  primarie  e  vincoli  relazionali. 

Permette  di rendere  facilmente  persistenti  le    istanze  delle  nostre  classi,  il  nostro  compito  sarà  di
rendere accessibile una mole di preesistete di dati relazionali. Hibernate rende persistenti praticamente ogni classe Java che lo richieda senza eccessivi vincoli.

Ogni POJO (Plain Old  Java  Object)  disegnato  in  fase  di  modellazione  del  dominio  applicativo,  per  poter
essere  gestito  da  Hibernate  deve  semplicemente  aderire  alle  fondamentali  regle  dei  più pratici javabeans: metodi pubblici getXXX e setXXX per le proprietà persistenti. 

Una  corretta  configurazione  del  framework  di  persistenza  eviterà  la  stesura    della  quasi totalità del codice SQL.
Il motore persistente di Hibernate può occuparsi di tutto il lavoro necessario per estrarre, inserire  e  modificare  i  dati  che  costituiscono  lo  stato  degli  oggetti  del  nostro  dominio applicativo generando autonomamente e in tutta trasparenza i comandi e le interrogazioni SQL necessari.

Il progetto Hibernate è legato al celeberrimo application Server JBoss, nel quale si fonde la parte di gestione della persistenza dei dati. Hibernate può essere utilizzato sia all’interno di  un  container  (es.  Tomcat),  sia  in  applicazioni  stand-alone  provvedendo  da  se  alla connessione verso il db relazionale oppure utilizzandone di già predisposte.

Il cuore di Hibernate è di circa 50.000 righe di codice tutte open e distribuite con licenza LGPL e supporta numerosi Database come Oracle, DB2, PostgreSQL, MySQL.

La mappa della classificazione sismica dei comuni italiani

April 7th, 2009
Comments Off

Con l’Ordinanza del Presidente del Consiglio dei Ministri n. 3274 del 20/03/2003 viene effettuata la classificazione sismica di ogni singolo comune.

In base alla zona di classificazione sismica, i nuovi edifici costruiti, così come quelli già esistenti durante le fasi di ristrutturazioni, devono adeguarsi alle corrispondenti normative vigenti antisismiche.

Secondo l’OPCM n. 3274 i comuni italiani sono stati classificati in 4 categorie in base al loro rischio sismico, calcolato sia per frequenza che per intensità degli eventi.

  • Zona 1: sismicità elevata-catastrofica
  • Zona 2: sismicità medio-alta
  • Zona 3: sismicità bassa
  • Zona 4: sismicità irrilevante

Scarica la mappa per Google Earth

Fonte: Dipartimento della Protezione Civile - INGV

Ho imparato - Octavian Paler

April 6th, 2009
Comments Off

Ho imparato che non puoi obbligare qualcuno ad amarti. Tutto ciò che puoi fare è essere una persona amabile. Il resto dipende dagli altri.

Ho imparato che ciò che è importante per me, per gli altri non lo è affatto.

Ho imparato che guadagnarsi la fiducia può durare anni, e che in soli pochi secondi la puoi perdere. Ho imparato che non importa CHE cosa hai nella vita ma CHI ti è vicino durante la vita.

Ho imparato che te la puoi cavare e che il fascino può esserti utile per circa 15 minuti. Dopo, però, sarebbe bene che tu sapessi qualcosa.

Ho imparato che non ti devi rapportare a ciò che gli altri sanno fare meglio, ma a ciò che tu puoi fare.

Ho imparato che non è importante ciò che accade alla gente, ma ciò che io posso fare per risolvere i loro problemi.

Ho imparato che in qualunque modo tagli, qualunque cosa ha due facciate.

Ho imparato che quando ti separi dalle persone care, lo devi fare con delle parole calde. Potrebbe essere l’ultima volta che le vedi.

Ho imparato che puoi ancora continuare per molto tempo dopo che hai detto di non farcela più.

Ho imparato che gli eroi sono coloro che fanno ciò che si deve fare, quando si deve fare, indifferentemente da quali sono le conseguenze.

Ho imparato che ci sono persone che ti amano ma non lo sanno dimostrare.

Ho imparato che quando sono arrabbiato ho il DIRITTO di esserlo. Però non ho il diritto di essere anche cattivo.

Ho imparato che l’amicizia autentica continua ad esistere anche a distanza. Ciò è valido anche per l’amore autentico.

Ho imparato che se qualcuno non ti ama come TU vorresti, ciò non significa che non ti ama con tutta la sua anima.

Ho imparato che per quanto buono possa essere un amico, comunque ogni tanto ti ferirà, e tu devi perdonarlo per questo.

Ho imparato che non è sempre sufficiente essere perdonato dagli altri. Qualche volta devi imparare a perdonare te stesso.

Ho imparato che indipendentemente da quanto soffri, il Mondo non si fermerà a causa del tuo dolore.

Ho imparato che il passato e le circostanze potrebbero influenzare la tua personalità. Però sarai TU il responsabile di ciò che diventerai.

Ho imparato che se due persone litigano non significa che non si amano. Ma nemmeno il fatto che non litigano dimostra che si amano.

Ho imparato che a volte devi mettere la persona al primo posto, non le sue azioni.

Ho imparato che due persone possono guardare la stessa cosa e vedere due cose totalmente diverse.

Ho imparato che indipendentemente dalle conseguenze, coloro che sono onesti arrivano più lontano nella vita.

Ho imparato che la tua vita può essere cambiata in poche ore da gente che neanche ti conosce.

Ho imparato che persino quando pensi di non avere più niente da dare, se un amico ti chiama troverai la forza di aiutarlo.

Ho imparato che lo scrivere, come il parlare, può dare sollievo ai dolori dell’anima.

Ho imparato che le persone alle quali tieni di più ti vengono portate via troppo in fretta…

Ho imparato che è troppo difficile renderti conto dove mettere una linea tra l’essere gentile, il non ferire le persone e il sostenere le proprie opinioni.

Ho imparato ad amare per poter essere amato.

Motore di ricerca

April 5th, 2009
Comments Off

Un motore di ricerca è un sistema automatico che analizza un insieme di dati spesso da lui stesso raccolti e restituisce un indice dei contenuti disponibili classificandoli in base a formule matematiche che ne indichino il grado di rilevanza data una determinata chiave di ricerca.

Uno dei campi in cui i motori di ricerca trovano maggiore utilizzo è quello dell’Information Retrieval e nel web.

Esistono numerosi motori di ricerca attivi sul Web. Il più utilizzato, su scala mondiale (con un indice che supera gli 8 miliardi di pagine), è Google; molto usati anche Live (motore di ricerca della Microsoft), Yahoo! , Ask. Da segnalare il tentativo di creare il primo motore di ricerca europeo, Quaero concorrente di Google con una iniziativa franco-germanica. Il progetto, stimato attorno ai 400 milioni di dollari, è stato abbandonato dopo pochi mesi per la rinuncia da parte della compagnia tedesca.

Fra i motori di ricerca nati in Italia quelli maggiormente utilizzati nel nostro paese sono Libero, Virgilio. Tuttavia non sono veri motori di ricerca giacché si limitano a riutilizzare Google. Libero e altri ne evidenziano chiaramente il logo, mentre Virgilio ne usa i risultati senza evidenziarne la fonte, limitandosi solo ad aggiungere alcuni propri risultati sponsorizzati.