Προγραμματισμός

Ξεκινήστε με την αδρανοποίηση

Είναι καλό να κατανοήσετε την ανάγκη για αντιστοίχιση αντικειμένων / σχεσιακή (ORM) σε εφαρμογές Java, αλλά μάλλον ανυπομονείτε να δείτε το Hibernate σε δράση. Θα ξεκινήσουμε δείχνοντάς σας ένα απλό παράδειγμα που αποδεικνύει μέρος της δύναμής του.

Όπως ίσως γνωρίζετε, είναι παραδοσιακό να ξεκινά ένα βιβλίο προγραμματισμού με ένα παράδειγμα "Hello World". Σε αυτό το κεφάλαιο, ακολουθούμε αυτήν την παράδοση εισάγοντας το Hibernate με ένα σχετικά απλό πρόγραμμα "Hello World". Ωστόσο, η απλή εκτύπωση ενός μηνύματος σε ένα παράθυρο κονσόλας δεν θα είναι αρκετή για να δείξει πραγματικά την αδρανοποίηση. Αντ 'αυτού, το πρόγραμμά μας θα αποθηκεύει νέα αντικείμενα στη βάση δεδομένων, θα τα ενημερώνει και θα εκτελεί ερωτήματα για να τα ανακτήσει από τη βάση δεδομένων.

Εκτός από το κανονικό παράδειγμα "Hello World", παρουσιάζουμε τα βασικά API αδρανοποίησης και δίνουμε λεπτομέρειες για μια βασική διαμόρφωση.

"Γεια σου Κόσμος" με την αδρανοποίηση

Οι εφαρμογές αδρανοποίησης καθορίζουν τις μόνιμες κλάσεις που "χαρτογραφούνται" σε πίνακες βάσης δεδομένων. Το παράδειγμα "Hello World" αποτελείται από μία κλάση και ένα αρχείο αντιστοίχισης. Ας δούμε πώς μοιάζει μια απλή μόνιμη τάξη, πώς καθορίζεται η αντιστοίχιση και μερικά από τα πράγματα που μπορούμε να κάνουμε με τις παρουσίες της μόνιμης τάξης που χρησιμοποιούν το Hibernate.

Ο στόχος της δειγματοληπτικής μας εφαρμογής είναι η αποθήκευση μηνυμάτων σε μια βάση δεδομένων και η ανάκτησή τους για προβολή. Η εφαρμογή έχει μια απλή επίμονη τάξη, Μήνυμα, που αντιπροσωπεύει αυτά τα εκτυπώσιμα μηνύματα. Μας Μήνυμα η τάξη εμφανίζεται στην καταχώριση 1.

Λίστα 1. Μήνυμα.java: Μια απλή επίμονη τάξη

γεια σου πακέτο δημόσια τάξη Μήνυμα {ιδιωτικό Long id; ιδιωτικό κείμενο συμβολοσειράς; ιδιωτικό μήνυμα nextMessage; ιδιωτικό μήνυμα () {} δημόσιο μήνυμα (κείμενο συμβολοσειράς) {this.text = text; } δημόσιο Long getId () {return id; } private void setId (Long id) {this.id = id; } δημόσια συμβολοσειρά getText () {επιστροφή κειμένου; } public void setText (κείμενο συμβολοσειράς) {this.text = text; } δημόσιο μήνυμα getNextMessage () {return nextMessage; } public void setNextMessage (μήνυμα nextMessage) {this.nextMessage = nextMessage; }} 

Μας Μήνυμα Η κλάση έχει τρία χαρακτηριστικά: το χαρακτηριστικό αναγνωριστικό, το κείμενο του μηνύματος και μια αναφορά σε άλλο Μήνυμα. Το χαρακτηριστικό αναγνωριστικό επιτρέπει στην εφαρμογή να έχει πρόσβαση στην ταυτότητα της βάσης δεδομένων - την πρωτεύουσα τιμή κλειδιού - ενός μόνιμου αντικειμένου. Εάν δύο περιπτώσεις Μήνυμα έχουν την ίδια τιμή αναγνωριστικού, αντιπροσωπεύουν την ίδια σειρά στη βάση δεδομένων. Επιλέξαμε Μακρύς για τον τύπο του χαρακτηριστικού αναγνωριστικού μας, αλλά αυτό δεν είναι απαίτηση. Η αδρανοποίηση επιτρέπει σχεδόν οτιδήποτε για τον τύπο αναγνωριστικού, όπως θα δείτε αργότερα.

Μπορεί να έχετε παρατηρήσει ότι όλα τα χαρακτηριστικά του Μήνυμα τάξη έχουν μεθόδους προσπέλασης ιδιοτήτων τύπου JavaBean. Η τάξη έχει επίσης κατασκευαστή χωρίς παραμέτρους. Οι συνεχείς τάξεις που χρησιμοποιούμε στα παραδείγματα μας θα έχουν σχεδόν πάντα κάτι τέτοιο.

Παρουσιάσεις του Μήνυμα Η τάξη μπορεί να διαχειρίζεται (γίνεται επίμονη) από το Hibernate, αλλά δεν το κάνουν έχω να είναι. Από το Μήνυμα Το αντικείμενο δεν εφαρμόζει καμία κλάση ή διασύνδεση για το Hibernate, μπορούμε να το χρησιμοποιήσουμε όπως οποιαδήποτε άλλη κλάση Java:

Μήνυμα μηνύματος = νέο μήνυμα ("Hello World"); System.out.println (message.getText ()); 

Αυτό το κομμάτι κώδικα κάνει ακριβώς αυτό που περιμένουμε από τις εφαρμογές "Hello World": Εκτυπώνει "Γειά σου Κόσμε" στην κονσόλα. Μπορεί να φαίνεται ότι προσπαθούμε να είμαστε χαριτωμένοι εδώ. Στην πραγματικότητα, επιδεικνύουμε ένα σημαντικό χαρακτηριστικό που διακρίνει το Hibernate από κάποιες άλλες λύσεις επιμονής, όπως το EJB (Enterprise JavaBean). Η επίμονη τάξη μας μπορεί να χρησιμοποιηθεί σε οποιοδήποτε πλαίσιο εκτέλεσης - δεν απαιτείται ειδικό κοντέινερ. Φυσικά, ήρθατε εδώ για να δείτε την ίδια την Αδρανοποίηση, οπότε ας σώσουμε ένα νέο Μήνυμα στη βάση δεδομένων:

Session session = getSessionFactory (). OpenSession (); Συναλλαγή tx = session.beginTransaction (); Μήνυμα μηνύματος = νέο μήνυμα ("Hello World"); session.save (μήνυμα); tx.commit (); session.close (); 

Αυτός ο κωδικός καλεί την αδρανοποίηση Συνεδρίαση και Συναλλαγή διεπαφές. (Θα φτάσουμε σε αυτό getSessionFactory () σύντομα.) Καταλήγει σε εκτέλεση κάτι παρόμοιο με το ακόλουθο SQL:

εισαγωγή σε τιμές MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) (1, "Hello World", null) 

Περίμενε — το MESSAGE_ID στήλη αρχικοποιείται σε μια παράξενη τιμή. Δεν ορίσαμε το ταυτότητα Ιδιοκτησία του μήνυμα οπουδήποτε, έτσι θα περιμέναμε να είναι μηδενικό, σωστά? Στην πραγματικότητα, το ταυτότητα το ακίνητο είναι ξεχωριστό: Είναι ένα ιδιότητα αναγνωριστικού—Έχει μια μοναδική τιμή που δημιουργήθηκε. (Θα συζητήσουμε πώς δημιουργείται η τιμή αργότερα.) Η τιμή εκχωρείται στο Μήνυμα παράδειγμα από το Hibernate όταν σώσει() λέγεται.

Για αυτό το παράδειγμα, υποθέτουμε ότι το ΜΗΝΥΜΑΤΑ υπάρχει ήδη πίνακας. Φυσικά, θέλουμε το πρόγραμμα "Hello World" να εκτυπώσει το μήνυμα στην κονσόλα. Τώρα που έχουμε ένα μήνυμα στη βάση δεδομένων, είμαστε έτοιμοι να το δείξουμε αυτό. Το επόμενο παράδειγμα ανακτά όλα τα μηνύματα από τη βάση δεδομένων, με αλφαβητική σειρά και τα εκτυπώνει:

Session newSession = getSessionFactory (). OpenSession (); Συναλλαγή newTransaction = newSession.beginTransaction (); Λίστα μηνυμάτων = newSession.find ("από το μήνυμα ως παραγγελία με m.text asc"); System.out.println (message.size () + "found (s) message (s):"); για (Iterator iter = messages.iterator (); iter.hasNext ();) {Μήνυμα μηνύματος = (Μήνυμα) iter.next (); System.out.println (message.getText ()); } newTransaction.commit (); newSession.close (); 

Η κυριολεκτική συμβολοσειρά "από Μήνυμα ως παραγγελία από m.text asc" είναι ένα ερώτημα Hibernate, που εκφράζεται στην αντικειμενοστρεφή Hibernate Query Language (HQL). Αυτό το ερώτημα μεταφράζεται εσωτερικά στην ακόλουθη SQL όταν εύρημα() λέγεται:

επιλέξτε m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID από MESSAGES m παραγγελία κατά m.MESSAGE_TEXT asc 

Το τμήμα κώδικα εκτυπώνει:

Βρέθηκαν 1 μήνυμα: Γεια Κόσμος 

Εάν δεν έχετε χρησιμοποιήσει ποτέ ένα εργαλείο ORM όπως το Hibernate στο παρελθόν, πιθανότατα περιμένατε να δείτε τις δηλώσεις SQL κάπου στον κώδικα ή τα μεταδεδομένα. Δεν είναι εκεί. Όλη η SQL δημιουργείται κατά το χρόνο εκτέλεσης (στην πραγματικότητα κατά την εκκίνηση, για όλες τις επαναχρησιμοποιήσιμες δηλώσεις SQL).

Για να επιτρέψει αυτή τη μαγεία να συμβεί, το Hibernate χρειάζεται περισσότερες πληροφορίες σχετικά με το πώς το Μήνυμα η τάξη πρέπει να γίνει επίμονη. Αυτές οι πληροφορίες παρέχονται συνήθως σε Έγγραφο χαρτογράφησης XML. Το έγγραφο χαρτογράφησης καθορίζει, μεταξύ άλλων, πώς οι ιδιότητες του Μήνυμα χάρτης τάξης σε στήλες του ΜΗΝΥΜΑΤΑ τραπέζι. Ας δούμε το έγγραφο χαρτογράφησης στην Λίστα 2.

Λίστα 2. Μια απλή αντιστοίχιση XML αδρανοποίησης

Το έγγραφο χαρτογράφησης λέει στο Hibernate ότι το Μήνυμα τάξη πρέπει να διατηρηθεί στο ΜΗΝΥΜΑΤΑ πίνακα, που η ιδιότητα του αναγνωριστικού αντιστοιχεί σε μια στήλη με το όνομα MESSAGE_ID, ότι η ιδιότητα κειμένου αντιστοιχεί σε μια στήλη με το όνομα ΚΕΙΜΕΝΟ ΜΗΝΥΜΑΤΟΣ, και ότι η ιδιότητα ονομάστηκε επόμενο μήνυμα είναι ένας σύνδεσμος με πολλαπλότητα προς ένα που αντιστοιχεί σε μια στήλη με το όνομα NEXT_MESSAGE_ID. (Μην ανησυχείτε για τις άλλες λεπτομέρειες προς το παρόν.)

Όπως μπορείτε να δείτε, το έγγραφο XML δεν είναι δύσκολο να κατανοηθεί. Μπορείτε εύκολα να το γράψετε και να το συντηρήσετε με το χέρι. Όποια μέθοδο και αν επιλέξετε, το Hibernate έχει αρκετές πληροφορίες για να δημιουργήσει πλήρως όλες τις δηλώσεις SQL που θα χρειαζόταν για εισαγωγή, ενημέρωση, διαγραφή και ανάκτηση παρουσιών του Μήνυμα τάξη. Δεν χρειάζεται πλέον να γράφετε αυτές τις δηλώσεις SQL με το χέρι.

Σημείωση
Πολλοί προγραμματιστές Java έχουν παραπονεθεί για το "κόλαση μεταδεδομένων" που συνοδεύει την ανάπτυξη του J2EE. Μερικοί πρότειναν μια μετακίνηση από τα μεταδεδομένα XML πίσω στον απλό κώδικα Java. Παρόλο που επικροτούμε αυτήν την πρόταση για ορισμένα προβλήματα, το ORM αντιπροσωπεύει μια περίπτωση όπου τα μεταδεδομένα που βασίζονται σε κείμενο είναι πραγματικά απαραίτητα. Το Hibernate έχει λογικές προεπιλογές που ελαχιστοποιούν την πληκτρολόγηση και έναν ορισμό ώριμου τύπου εγγράφου που μπορεί να χρησιμοποιηθεί για αυτόματη συμπλήρωση ή επικύρωση σε συντάκτες. Μπορείτε ακόμη και να δημιουργήσετε αυτόματα μεταδεδομένα με διάφορα εργαλεία.

Τώρα, ας αλλάξουμε το πρώτο μας μήνυμα και, ενώ είμαστε σε αυτό, δημιουργήστε ένα νέο μήνυμα που σχετίζεται με το πρώτο, όπως φαίνεται στην Λίστα 3.

Λίστα 3. Ενημέρωση μηνύματος

Session session = getSessionFactory (). OpenSession (); Συναλλαγή tx = session.beginTransaction (); // 1 είναι το δημιουργημένο αναγνωριστικό του πρώτου μηνύματος Μήνυμα μηνύματος = (Μήνυμα) session.load (Message.class, νέο Long (1)); message.setText ("Χαιρετισμοί Earthling"); Μήνυμα nextMessage = νέο μήνυμα ("Πάρε με στον ηγέτη σου (παρακαλώ)"); message.setNextMessage (nextMessage); tx.commit (); session.close (); 

Αυτός ο κωδικός καλεί τρεις δηλώσεις SQL μέσα στην ίδια συναλλαγή:

επιλέξτε m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID από MESSAGES m όπου m.MESSAGE_ID = 1 εισάγετε σε τιμές MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) (2, "Μεταβείτε στον ηγέτη σας (παρακαλώ)", null) ενημερώστε MESSAGES ορίστε MESSAGE_TEXT = "Χαιρετισμοί Earthling", NEXT_MESSAGE_ID = 2 όπου MESSAGE_ID = 1 

Παρατηρήστε πώς το Hibernate εντόπισε την τροποποίηση στο κείμενο και επόμενο μήνυμα ιδιότητες του πρώτου μηνύματος και ενημερώνεται αυτόματα η βάση δεδομένων. Έχουμε εκμεταλλευτεί τη λειτουργία αδρανοποίησης που ονομάζεται αυτόματο βρώμικο έλεγχο: αυτή η λειτουργία μας εξοικονομεί την προσπάθεια ρητής ερώτησης του Hibernate να ενημερώσει τη βάση δεδομένων όταν τροποποιούμε την κατάσταση ενός αντικειμένου μέσα σε μια συναλλαγή. Ομοίως, μπορείτε να δείτε ότι το νέο μήνυμα έγινε επίμονο όταν δημιουργήθηκε μια αναφορά από το πρώτο μήνυμα. Αυτό το χαρακτηριστικό ονομάζεται αποθηκεύστε διαδοχικά: μας εξοικονομεί την προσπάθεια να κάνουμε το νέο αντικείμενο επίμονο καλώντας σώσει(), εφ 'όσον είναι προσβάσιμο από μια ήδη επίμονη παρουσία. Επίσης, παρατηρήστε ότι η σειρά των δηλώσεων SQL δεν είναι ίδια με τη σειρά με την οποία ορίζουμε τιμές ιδιοτήτων. Το Hibernate χρησιμοποιεί έναν εξελιγμένο αλγόριθμο για τον προσδιορισμό μιας αποτελεσματικής παραγγελίας που αποφεύγει παραβιάσεις περιορισμών ξένου κλειδιού βάσης δεδομένων, αλλά εξακολουθεί να είναι επαρκώς προβλέψιμος για τον χρήστη. Αυτό το χαρακτηριστικό ονομάζεται συναλλακτική εγγραφή.

Εάν εκτελέσουμε ξανά το "Hello World", εκτυπώνει:

Βρέθηκαν 2 μηνύματα: Χαιρετισμοί Earthling Πάρε με στον ηγέτη σου (παρακαλώ) 

Εδώ θα ακολουθήσουμε την εφαρμογή "Hello World". Τώρα που έχουμε τελικά κάποιον κώδικα, θα κάνουμε ένα βήμα πίσω και θα παρουσιάσουμε μια επισκόπηση των βασικών API του Hibernate.

Κατανόηση της αρχιτεκτονικής

Οι διεπαφές προγραμματισμού είναι το πρώτο πράγμα που πρέπει να μάθετε για το Hibernate για να το χρησιμοποιήσετε στο επίπεδο επιμονής της εφαρμογής σας. Ένας κύριος στόχος του σχεδιασμού API είναι να διατηρηθούν οι διεπαφές μεταξύ των στοιχείων του λογισμικού όσο το δυνατόν πιο στενές. Στην πράξη, ωστόσο, τα API ORM δεν είναι ιδιαίτερα μικρά. Μην ανησυχείτε όμως. δεν χρειάζεται να καταλάβετε όλες τις διεπαφές Hibernate ταυτόχρονα. Το παρακάτω σχήμα απεικονίζει τους ρόλους των πιο σημαντικών διεπαφών αδρανοποίησης στα επίπεδα των επιχειρήσεων και της επιμονής.

Δείχνουμε το επιχειρηματικό επίπεδο πάνω από το επίπεδο επιμονής, καθώς το επιχειρηματικό επίπεδο ενεργεί ως πελάτης του επιπέδου επιμονής σε μια παραδοσιακά εφαρμοσμένη εφαρμογή. Σημειώστε ότι ορισμένες απλές εφαρμογές ενδέχεται να μην διαχωρίζουν καθαρά την επιχειρηματική λογική από τη λογική επιμονής. αυτό είναι εντάξει - απλώς απλοποιεί το διάγραμμα.

Οι διεπαφές αδρανοποίησης που φαίνονται στο παραπάνω σχήμα μπορούν να ταξινομηθούν περίπου ως εξής:

  • Διεπαφές που καλούνται από εφαρμογές για την εκτέλεση βασικών CRUD (δημιουργία / ανάγνωση / ενημέρωση / διαγραφή) και λειτουργίες ερωτημάτων. Αυτές οι διασυνδέσεις είναι το βασικό σημείο εξάρτησης της επιχειρησιακής λογικής / λογικής ελέγχου από το Hibernate. Περιλαμβάνουν Συνεδρίαση, Συναλλαγή, και Ερώτηση.
  • Διεπαφές που απαιτούνται από τον κώδικα υποδομής εφαρμογών για να διαμορφώσετε το Hibernate, το πιο σημαντικό, το Διαμόρφωση τάξη.
  • Επιστροφή κλήσης διασυνδέσεις που επιτρέπουν στην εφαρμογή να αντιδρά σε γεγονότα που συμβαίνουν στο Hibernate, όπως Αναχαιτιστής, Κύκλος ζωής, και Ισχύει.
  • Διεπαφές που επιτρέπουν την επέκταση της ισχυρής λειτουργίας χαρτογράφησης του Hibernate, όπως Τύπος χρήστη, Τύπος σύνθετου χρήστη, και ΑναγνωριστικόGenerator. Αυτές οι διεπαφές εφαρμόζονται με κωδικό υποδομής εφαρμογής (εάν είναι απαραίτητο).

Το Hibernate χρησιμοποιεί υπάρχοντα API Java, συμπεριλαμβανομένων των JDBC (Java Database Connectivity), Java Transaction API (JTA) και Java Naming and Directory Interface (JNDI). Το JDBC παρέχει ένα στοιχειώδες επίπεδο αφαίρεσης λειτουργικότητας που είναι κοινό σε σχεσιακές βάσεις δεδομένων, επιτρέποντας σχεδόν σε οποιαδήποτε βάση δεδομένων με πρόγραμμα οδήγησης JDBC να υποστηρίζεται από το Hibernate. Τα JNDI και JTA επιτρέπουν την ενσωμάτωση του Hibernate με διακομιστές εφαρμογών J2EE.

Σε αυτήν την ενότητα, δεν καλύπτουμε τη λεπτομερή σημασιολογία των μεθόδων API Hibernate, απλώς τον ρόλο καθεμιάς από τις κύριες διεπαφές. Μπορείτε να βρείτε τις περισσότερες από αυτές τις διεπαφές στο πακέτο net.sf.hibernate. Ας ρίξουμε μια σύντομη ματιά σε κάθε διεπαφή με τη σειρά.

Οι βασικές διεπαφές

Οι πέντε πυρήνες διασυνδέσεις χρησιμοποιούνται σχεδόν σε κάθε εφαρμογή Hibernate. Χρησιμοποιώντας αυτές τις διεπαφές, μπορείτε να αποθηκεύσετε και να ανακτήσετε επίμονα αντικείμενα και να ελέγξετε τις συναλλαγές.

Διεπαφή συνεδρίας

$config[zx-auto] not found$config[zx-overlay] not found