1。継承マッピング
継承は、重要なオブジェクト指向の機能です。コードの使用を実装し、関係モデルにも相続関係があります。この相続関係は、実際には列挙関係と見なすことができます。多くのサブタイプを型で列挙できます。これらのサブタイプは、親オブジェクトとの相続関係を形成します。列挙できる列挙のほとんどは、継承マップと見なすことができます。したがって、この列挙関係は、継承マップと見なすことができます。たとえば、動物は抽象的なクラスであり、他の動物、豚、猫などの親クラスであり、下の図に示すように相続関係です。
この継承マッピングは、リレーショナルモデルに変換された後にテーブルを生成します。では、このテーブルはこれら2つのタイプをどのように区別しますか?リレーショナルフィールドを使用すると、テーブルにタイプフィールドを追加し、キーワードを使用してオブジェクトのタイプを示す必要があります。したがって、上記の図のオブジェクトモデルに対応するテーブル構造は次のとおりです。
テーブル構造を生成するときは、対応するフィールドタイプを追加する必要があるため、対応するマップ差別器をマッピングファイルに追加する必要があります。ここでは、識別子値属性を使用する必要があります。
1。クラスファイル
クラスファイルに注意を払う必要はありません。執筆時点での相続関係に注意を払ってください。
リスト:アニマルクラスコード、基本的なプロパティを追加するだけです。
パッケージcom.src.hibernate; public class Animal {// ID番号プライベートint id; public int getid(){return id; } public void setid(int id){this.id = id; } //名前プライベート文字列名; public string getName(){return name; } public void setName(string name){this.name = name; } //ジェンダープライベートブールセックス; public boolean issex(){return sex; } public void setsex(boolean sex){this.sex = sex; }}リスト2:鳥と豚のクラス、基本的な特性を追加し、動物のクラスを継承します。
パッケージcom.src.hibernate;パブリッククラスの鳥は動物を拡張します{//高さのプライベートint height; public int getheight(){return height; } public void setheight(int height){this.height = height; }}パッケージcom.src.hibernate;パブリッククラスの豚は動物を拡張します{//重量のプライベートint weight; public int getWeight(){return weight; } public void setweight(int weight){this.weight = weight; }} 2。マップファイル
対応するマッピングをマッピングファイルに追加する必要があります。 1つのマッピングファイルのみをモデルに追加する必要があります。これは、1つのテーブルのみが生成されるため、対応するサブクラスマッピングがマッピングファイルに追加されるためです。 <subclass>タグを使用すると、識別子値がタグに追加されます。この識別器プロパティは、次のように、データベースにデータを書くときに書かれたタイプを示します。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapting-3.0.dtd"テーブル= "t_animal"> <id name = "id"> <generator // id> <! - 認証タグを追加し、idの後に配置する必要があります - > <差別列= "タイプ"/> <プロパティ名= "name"/> <財産名= "sex" type = "boolean"/> <subclass name = "com. name = "weight"/> </subclass> <subclass name = "com.src.hibernate.bird"差別value = "b"> <プロパティname = "height"/> </subclass> </class> </hibernate-mapping> <
3。分析結果
生成されたMySQLデータベーステーブルは、動物の基本的な属性を追加するだけでなく、豚と鳥の特性も追加します。追加された属性はマッピングファイルに<subclass>を使用して記述され、対応する識別子属性も追加されているため、対応する識別子列がデータベースに追加されます。生成されたテーブル構造は次のとおりです。
2。データ操作
1。データを書き込みます
データの読み取りおよび書き込み操作を実行する場合、クラスでの操作の使用に注意を払う必要があります。
public void testsave(){session session = null; try {//セッションオブジェクトセッション= hibernateutils.getSession(); //トランザクションsession.begintransaction()を開きます。豚豚= new Pig(); pig.setName( "Little Pig"); pig.setsex(true); pig.setweight(200); session.save(豚);鳥の鳥=新しい鳥(); bird.setname( "xiaoniao"); bird.setsex(true); bird.setheight(100); session.save(bird); session.getTransaction()。commive(); } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{hibernateutils.closessession(session); }}2。多型クエリゲットおよびHQL
基本的なクエリ方法では、負荷を使用してメソッドを取得する必要があります。ここでは、多型クエリに焦点を当てます。多型クエリとは、Hibernateがインスタンスを使用して、オブジェクトをロードするときに真のタイプのオブジェクトを識別できることを意味します。これにより、それが多型クエリになることができます。
注:多型クエリは、怠zyなロードをサポートしていません。つまり、ロード方法を使用する場合、マッピングファイルの怠zyなロードをfalseに設定する必要があります。
3。負荷遅延ロード
ロードは怠zyなロードをサポートします。オブジェクトをロードすると、実際にオブジェクトのプロキシが生成されます。したがって、多型クエリを使用する場合、次のように、マッピングファイルで怠zyなロードをfalseに設定する必要があります。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapting-3.0.dtd"表= "t_animal" lazy = "false"> <id name = "id"> <generator // id> <! - 認証タグを追加する必要があります。IDの後に配置する必要があります - > <差別列= "type"/> <プロパティ名= "name =" name "/> <プロパティname =" sex "type =" boolean "/> <subclass =" <プロパティ名= "weight"/> </subclass> <subclass name = "com.src.hibernate.bird"差別value = "b"> <プロパティ名= "height"/> </subclass> </class> </hibernate-mapping>
負荷の負荷方法は、負荷を使用して負荷を使用して、多型クエリをサポートし、構成ファイルで遅延荷重をfalseに設定するため、ここではロード方法を使用して対応するオブジェクトクラスをロードして取得できます。
public void testload(){session session = null; try {session = hibernateutils.getSession(); session.begintransaction();動物ani =(動物)session.load(animal.class、1); System.out.println(ani.getName()); //デフォルトでは負荷が怠lazyをサポートするため、動物のプロキシが表示されます//インスタンスは真のタイプの豚を識別できない//この場合、この場合はポリ型クエリをサポートしません} else {system.out.println( "私は豚ではない!"); } session.getTransaction()。compid(); } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{hibernateutils.closessession(session); }} 4.HQLクエリ
HQLは多型クエリをサポートしています。これは、主にクエリが実際のオブジェクトであり、プロキシを返さないためです。したがって、HQLは多型クエリをサポートします。さらに、クエリする場合は、クエリステートメントでテーブル名を使用せずに、クラス名を使用することに注意する必要があります。 hibernateは、次のように、クラス名に従って対応するテーブル名にマッピングします。
public void testload5(){session session = null; try {session = hibernateutils.getSession(); session.begintransaction();リスト<動物> list = session.createquery( "from animal")。list(); for(iterator iter = list.iterator(); iter.hasnext();){animal a =(animal)iter.next(); if(age of pig){system.out.println( "私は豚です!"); } else {system.out.println( "私は豚ではありません!"); }} session.getTransaction()。compid(); } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{hibernateutils.closessession(session); }}クエリの結果:
hibernate:select animal00_.idをid0_、animal0.nameとしてname0_、animal0_.sexとしてsex0_、animal0_.weight as height0_、heights0_、animal0.typeとしてt_animal animal0_からtype0_ i a am a piglet!私は豚ではありません!私はピグレットです!私は豚ではありません!
3.継承マッピングのための3つの戦略
1。クラスあたりのテーブル階層
インターフェイスの支払いとそのいくつかの実装クラスがあるとします:クレジットカードペイメント、キャッシュペイ、およびchequepayment。次に、「クラスあたりのテーブル階層」のマッピングコードは次のとおりです。
<class name = "支払い"テーブル= "支払い"> <id name = "id" type = "long" column = "pained_id"> <generator/> </id> <差別列= "payment_type" type "type =" string "/> <プロパティ名=" column = "cctype"/> ... </subclass> <subclass name = "cashpayment"差別者-value = "case"> ... </subclass> <subclass name = "chequepayment"差別者値= "> ... </subclass> </class>
この戦略を採用するには、1つのテーブルのみが必要です。大きな制限があります。CCTypeなどのサブクラスによって定義されたフィールドには、非ヌルの制約がないことが必要です。
2。サブクラスごとに1つのテーブル
上記の例のクラスでは、「サブクラスごとに1つのテーブル」のマッピング戦略が採用されており、コードは次のとおりです。
<class name = "支払い"テーブル= "支払い"> <id name = "id" type = "long" column = "payment_id"> <generator/> </id> <プロパティ名= "colummen =" rument "/> ... <joined-subclass name =" creditcardpayment "table =" credit_payment "> name = "CashPayment" Table = "Cash_Payment"> <key column = "Payune_id"/> <Property name = "CreditCardType" column = "cctype"/>
4つのテーブルが必要です。 3つのサブクラステーブルは、プライマリキーを介してスーパークラステーブルに関連付けられています(したがって、関係モデルは実際には1対1の関連性です)。
3.各サブクラスにはテーブル(サブクラスごとのテーブル)があり、判別器を使用します
「サブクラスごとに1つのテーブル」のマッピング戦略では、Hibernateの実装には識別子フィールドは必要ありませんが、他のオブジェクト/リレーショナルマッピングツールは、スーパークラステーブルのタイプの識別子列を必要とするHibernateとは異なる実装方法を使用します。 Hibernateが採用する方法は実装がより困難ですが、関係(データベース)の観点からは、より正確です。識別フィールドを使用して「サブクラスごとに1つのテーブル」戦略を使用することをいとわない場合は、<subclass>を<join>で使用できます。
<class name = "支払い"テーブル= "支払い"> <id name = "id" type = "long" column = "pained_id"> <generator/> </id> <差別列= "payment_type" type "type =" string "/> <プロパティ名=" name = "creditcardtype" column = "cctype"/> ... </join> </subclass> <subclass name = "cashpayment"差別者value = "case"> <join table = "cash_payment"> fetch = "select"> ... </join> </subclass> </class> </class>
オプションの宣言Fetch = "Select"は、スーパークラスをクエリするときに外部結合を使用してサブクラスのChequepaymentのデータを取得しないことを冬眠に伝えるために使用されます。