1. Pemetaan warisan
Warisan adalah fitur yang berorientasi objek yang penting. Ini mengimplementasikan penggunaan kode dan juga memiliki hubungan warisan dalam model hubungan. Hubungan warisan ini sebenarnya dapat dianggap sebagai hubungan enumerasi. Banyak subtipe dapat disebutkan dalam suatu jenis. Subtipe ini membentuk hubungan warisan dengan objek induk. Sebagian besar enumerasi yang dapat disebutkan dapat dianggap sebagai peta warisan. Oleh karena itu, hubungan enumerasi ini dapat dianggap sebagai peta warisan. Misalnya, hewan adalah kelas abstrak, yang merupakan kelas induk dari hewan lain, babi, kucing, dll., Dan mereka adalah hubungan warisan, seperti yang ditunjukkan pada gambar di bawah ini:
Pemetaan warisan ini akan menghasilkan tabel setelah dikonversi menjadi model relasional. Jadi bagaimana tabel ini membedakan antara kedua jenis ini? Gunakan bidang relasional, Anda perlu menambahkan jenis bidang ke tabel dan menggunakan kata kunci untuk menunjukkan jenis objek. Oleh karena itu, struktur tabel yang sesuai dengan model objek pada gambar di atas adalah sebagai berikut:
Saat menghasilkan struktur tabel, Anda perlu menambahkan jenis bidang yang sesuai, sehingga Anda perlu menambahkan diskriminator peta yang sesuai ke file pemetaan. Di sini Anda perlu menggunakan atribut nilai diskriminator.
1. File kelas
Tidak perlu memperhatikan file kelas, cukup perhatikan hubungan warisan di antara mereka saat menulis.
Daftar: Kode kelas hewan, Anda hanya perlu menambahkan properti dasar.
paket com.src.hibernate; Hewan kelas publik {// Nomor id Private int ID; publik int getId () {return id; } public void setid (int id) {this.id = id; } // Nama nama string pribadi; public string getName () {return name; } public void setName (name string) {this.name = name; } // Jenis Kelamin Privat Boolean; public boolean issex () {return sex; } public void setSex (boolean sex) {this.sex = sex; }}Listing 2: Kelas Burung dan Babi, Tambahkan Sifat Dasar, dan mewarisi kelas hewan.
paket com.src.hibernate; Bird kelas publik memperluas hewan {// tinggi intr private int; publik int getHeight () {return height; } public void setHeight (int tinggi) {this.height = tinggi; }} paket com.src.hibernate; Babi kelas publik memperluas hewan {// berat badan pribadi int; public int getweight () {return weight; } public void setWeight (int weight) {this.weight = weight; }} 2. File peta
Pemetaan yang sesuai perlu ditambahkan ke file pemetaan. Hanya satu file pemetaan yang perlu ditambahkan ke model, karena hanya satu tabel yang dihasilkan, pemetaan subclass yang sesuai ditambahkan ke file pemetaan. Gunakan tag <subclass>, dan nilai diskriminator ditambahkan ke tag. Properti diskriminator ini menunjukkan jenis apa yang ditulis saat menulis data dalam database, sebagai berikut:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <Hibernate-papping> <class name = "coMal. TABLE = "T_ANIMAL"> <id name = "id"> <generator // id> <!-tambahkan tag otentikasi dan harus ditempatkan setelah id-> <diskriminator kolom = "type"/> <properti nama = "name"/> <properti = "sex" type = "boolean"/> <subclass name = "comeN." name = "Weight"/> </subclass> <subklass name = "com.src.hibernate.bird" diskriminator-value = "b"> <name properti = "height"/> </subclass> </class> </hibernate-mapping>
3. Hasil Analisis
Tabel database MySQL yang dihasilkan tidak hanya akan menambahkan atribut dasar hewan, tetapi juga menambahkan sifat babi dan burung. Karena atribut yang ditambahkan ditulis menggunakan <subclass> dalam file pemetaan, dan atribut diskriminator yang sesuai juga ditambahkan, sehingga kolom diskriminator yang sesuai akan ditambahkan ke database. Struktur tabel yang dihasilkan adalah sebagai berikut:
2. Operasi Data
1. Tulis data
Saat melakukan operasi membaca dan menulis data, Anda perlu memperhatikan penggunaan operasi di kelas.
public void testSave () {session session = null; coba {// buat sesi sesi sesi = hibernateutils.getSession (); // buka transaksi session.begintransaction (); Babi babi = babi baru (); pig.setname ("babi kecil"); pig.setsex (true); Pig.setweight (200); session.save (babi); Burung burung = burung baru (); Bird.setname ("Xiaoniao"); Bird.setsex (true); Bird.setheight (100); session.save (burung); session.getTransaction (). Commit (); } catch (Exception e) {E.PrintStackTrace (); session.getTransaction (). rollback (); } akhirnya {hibernateutils.closesession (sesi); }}2. Kueri Polimorfik-Get dan HQL
Metode kueri dasar hanya membutuhkan menggunakan metode beban dan mendapatkan. Di sini kami fokus pada kueri polimorfik. Kueri polimorfik berarti bahwa hibernasi dapat menggunakan instanceof untuk mengidentifikasi jenis objek yang sebenarnya saat memuat suatu objek, sehingga dapat menjadi kueri polimorfik.
Catatan: Kueri polimorfik tidak mendukung pemuatan malas, yaitu, jika Anda menggunakan metode pemuatan, Anda perlu mengatur pemuatan malas ke false dalam file pemetaan.
3. Load Delay Loading
Muat mendukung pemuatan malas. Saat memuat objek, itu benar -benar menghasilkan proxy objek. Oleh karena itu, saat menggunakan kueri polimorfik, Anda perlu mengatur pemuatan malas menjadi false dalam file pemetaan, sebagai berikut:
<? XML Versi = "1.0"?> <! Doctype Hibernate-Mapping Public "-// Hibernate/Hibernate Mapping DTD 3.0 // EN" "http://hibernate.sourceForge.net/hibernate-papping-3.0.dtd"> <Hibernate-papping> <class name = "coMal. Table = "t_animal" malas = "false"> <id name = "id"> <generator // id> <!-tambahkan tag otentikasi dan harus ditempatkan setelah id-> <diskriminator kolom = "type"/> <name properti = "name"/> <properti nama = "sex" type = "boolean"/<name subsclass = "com. com. com. com. com.co com.co com.co com.co. diskriminator-value = "p"> <name properti = "bobot"/> </subsclass> <subkelas nama = "com.src.hibernate.bird" diskriminator-value = "b"> <nama properti = "tinggi"/> </subclass> </sclass> </hibernate-mapping>
Metode pemuatan beban, menggunakan beban untuk memuat, contoh ini mendukung kueri polimorfik, dan mengatur pemuatan yang tertunda ke false dalam file konfigurasi, sehingga metode pemuatan dapat digunakan di sini untuk memuat dan mendapatkan kelas objek yang sesuai.
public void testLoad () {session session = null; coba {session = hibernateutils.getSession (); session.begintransaction (); Hewan anius = (hewan) sesi. System.out.println (ani.getName ()); // Karena beban mendukung malas secara default, kita melihat proxy hewan // jadi instanceof tidak dapat mengidentifikasi babi tipe sejati // jadi beban tidak mendukung kueri polimorfik dalam kasus ini jika (ani instance babi) {system.out.println ("Saya seorang babi!"); } else {System.out.println ("Aku bukan babi!"); } session.getTransaction (). commit (); } catch (Exception e) {E.PrintStackTrace (); session.getTransaction (). rollback (); } akhirnya {hibernateutils.closesession (sesi); }} 4. Kueri HQL
HQL mendukung kueri polimorfik, yang terutama karena kueri adalah objek nyata dan tidak mengembalikan proxy. Oleh karena itu, HQL mendukung kueri polimorfik. Selain itu, saat meminta, Anda perlu memperhatikan untuk tidak menggunakan nama tabel dalam pernyataan kueri, tetapi menggunakan nama kelas. Hibernate akan memetakannya ke nama tabel yang sesuai sesuai dengan nama kelas, sebagai berikut:
public void testload5 () {session session = null; coba {session = hibernateutils.getSession (); session.begintransaction (); Daftar <En Animal> Daftar = session.createQuery ("From Animal"). List (); untuk (iterator iter = list.iterator (); iter.hasnext ();) {hewan a = (hewan) iter.next (); if (instance dari babi) {System.out.println ("Saya seorang babi!"); } else {System.out.println ("Aku bukan babi!"); }} session.getTransaction (). commit (); } catch (Exception e) {E.PrintStackTrace (); session.getTransaction (). rollback (); } akhirnya {hibernateutils.closesession (sesi); }}Hasil kueri:
Hibernate: Pilih animal0_.id sebagai id0_, animal0_.name as name0_, animal0_.sex as sex0_, animal0_.weight as weight0_, animal0_. Saya bukan babi! Saya seorang anak babi! Saya bukan babi!
3. Tiga strategi untuk pemetaan warisan
1. Tabel per Hirarki Kelas
Misalkan kami memiliki pembayaran antarmuka dan beberapa kelas implementasinya: creditcardpayment, pembayaran kas, dan pembayaran lak. Kemudian kode pemetaan "Tabel per Hirarki Kelas" adalah sebagai berikut:
<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID"> <generator/> </id> <discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/> ... <subclass name="CreditCardPayment" discriminator-value="CREDIT"> <property name="creditCardType" kolom = "cctype"/> ... </subclass> <subklass name = "cashpayment" diskriminator-value = "cash"> ... </subclass> <subkelas nama = "chequepayment" diskriminator-value = "check"> ... </subclass> </class>
Hanya satu tabel yang diperlukan untuk mengadopsi strategi ini. Ini memiliki batasan besar: ini mensyaratkan bahwa bidang yang ditentukan oleh subkelas, seperti CCTYPE, tidak dapat memiliki kendala non-nol.
2. Satu tabel per subkelas
Untuk kelas dalam contoh di atas, strategi pemetaan "satu tabel per subkelas" diadopsi, dan kodenya adalah sebagai berikut:
<class name = "pembayaran" Tabel = "pembayaran"> <id nama = "id" type = "long" column = "payment_id"> <generator/> </d> <name properti = "jumlah" kolom = "jumlah"/> ... <joined-subclass name = "creditcardpayment" TABLE = "credit_payment"> <Key-Subclass name = "creditCardPayment" TABLE = "credit_payment" <Key-Subclass COLMOMPER "/... name="CashPayment" table="CASH_PAYMENT"> <key column="PAYMENT_ID"/> <property name="creditCardType" column="CCTYPE"/> ... </joined-subclass> <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT"> <key column="PAYMENT_ID"/> ... </joined-subclass> </class>
Empat tabel diperlukan. Tiga tabel subkelas dikaitkan dengan tabel superclass melalui kunci primer (sehingga model hubungan sebenarnya adalah asosiasi satu-ke-satu).
3. Setiap subkelas memiliki tabel (tabel per subkelas), dan gunakan diskriminator
Perhatikan bahwa untuk strategi pemetaan "satu tabel per subkelas", implementasi hibernasi tidak memerlukan bidang diskriminator, sementara alat pemetaan objek/relasional lainnya menggunakan metode implementasi yang berbeda dari hibernate, yang membutuhkan kolom diskriminator tipe dalam tabel superclass. Metode yang diadopsi oleh Hibernate lebih sulit diimplementasikan, tetapi dari perspektif hubungan (database), itu lebih benar. Jika Anda bersedia menggunakan strategi "satu tabel per subkelas" dengan bidang penegasan, Anda dapat menggunakan <subclass> dengan <Fogn> sebagai berikut:
<class name="Payment" table="PAYMENT"> <id name="id" type="long" column="PAYMENT_ID"> <generator/> </id> <discriminator column="PAYMENT_TYPE" type="string"/> <property name="amount" column="AMOUNT"/> ... <subclass name="CreditCardPayment" discriminator-value="CREDIT"> <join table="CREDIT_PAYMENT"> <property name = "creditcardType" kolom = "cctype"/> ... </join> </subsclass> <subkelas nama = "cashpayment" diskriminator-value = "tunai"> <gabungan table = "cash_payment"> </joint> </subclass> <subkelas nama = "chequinePayment" "ceChePayment" "ce chequine" ce chequine " fetch = "SELECT"> ... </joint> </subclass> </slass> </class>
Deklarasi opsional Fetch = "Select" digunakan untuk memberi tahu Hibernate bahwa ketika menanyakan superclass, jangan gunakan gabungan eksternal untuk mengambil data pembayaran cairan subkelas.