1。双方向主要なキー関連
双方向の主要な主要な関連付けは、実際には1対1の主要なキー関連の特別なケースです。ただし、関連するオブジェクトの両端のマッピングファイルで<1対1>構成を実行する必要があり、さらに、メインマップの主キーの一方の端で外部外部キーアソシエーション属性を使用する必要があります。
ここでは、人とidcardを使用して議論します。人は一意のIDカードに対応し、IDカードも人をマッピングするため、これにより双方向の関連関係が生まれます。人の主な鍵は、主要な鍵と外国のキーの両方であるIDカードの主要な鍵でもあります。この関連関係は、双方向の1対1マッピングになります。これは、以下に示すように、関係モデルで表現できます。
図の2つのテーブルは、プライマリキーアソシエーションを使用しています。人の主な鍵はIDCardの主要な鍵であるため、Zhuの外国鍵の間に制約関係を形成し、一意性を確保し、それをオブジェクトモデルにマッピングし、下の図に示すように、人クラスとIDカードクラスの1対1の関係に変換します。
この1対1の関係は、前の記事でも<1対1>タグが使用されており、この1対1のマッピングが双方向であると述べたため、2つのオブジェクト間で同時に<1対1>を構成する必要があります。まず、IDCardに対応するクラスコードとマッピングファイルコードを見てみましょう。
1。idcardに対応する情報
idcard.javaクラス、idcardクラス、およびpersonクラスの間には1対1の関係があります。したがって、対応する個人属性をIDCardクラスに追加する必要があります。これは、マッピングファイルの外部キーに対応する属性を追加し、対応する外部キーアソシエーションクラスを設定することです。
パッケージcom.src.hibernate; public class idcard {// id属性private int id; public int getid(){return id; } public void setid(int id){this.id = id; } //カード番号属性プライベート文字列cardno; public string getCardno(){return cardno; } public void setcardno(string cardno){this.cardno = cardno; } //カード番号に対応する人々。パブリックパーソンgetPerson(){return person; } public void setPerson(person person){this.person = person; }}idcard.hbm.xmlマッピングファイルは、外部キー属性の人をマッピングファイルに追加し、対応する<1対1>タグを追加します。目的は、制約担当者クラスに1対1のマッピング関係を達成するように強制することです。最後に、強制制約関係を確保するために、マッピングで制約付き属性をTRUEに設定します。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! - > <hibernate-mapping> <class name = "com.src.hibernate.idcard" table = "idcard"> <id name = "id" type = "int" column = "personid"> <generator> <param name = "property"> person </param> </generator> </id> <propertion "type =" column " name = "person" constrained = "true"> </on-one> </class> </hibernate-mapping>
2。対応する情報
Person.javaクラスでは、基本属性を追加することに加えて、対応するIDCardクラスを属性として追加する必要があります。これは、1対1の双方向関連関係であるため、IDCardクラスもPersonクラスに追加する必要があります。同じ理由は、個人クラスの属性もIDCardクラスに追加されることです。
パッケージcom.src.hibernate;パブリッククラスの人{// 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; } // idcard private idcard idcard; public idcard getIdCard(){return idcard; } public void setidcard(idcard idcard){this.idcard = idcard; }}person.hbm.xmlマッピングファイル、このファイルの主要なキー生成戦略には、IDCardクラスによって相互に制限されているため、特別な要件はありません。その主キーと外部キーはどちらもIDカードの主要なキーです。さらに、1対1の関係であるため、<1対1>タグをマッピングファイルに追加して示す必要があります。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! - > <hibernate-mapping> <class name = "com.src.hibernate.person" table = "person"> <id name = "id" type = "int" column = "personator> </generator> </id> <プロパティ名=" name "type =" string "column =" personname ">デフォルトでは、プライマリキーに従ってロードします。つまり、関係フィールドの値を取得し、対戦相手の主要なキーに応じて関連するオブジェクトをロードします - > <1-One name = "idcard"> </on-1-one> </class> </hibernate-mapping> <
3。冬眠マッピングファイル
上記のクラスとマッピングファイルが構成された後、hibernate.cfg.xmlのデータベースマッピングに関する情報は、対応するデータベースを生成するときに対応する生成アイテムを見つけることができるように、2つの構成ファイルをHibernate構成ファイルに追加するために必要です。
<?xml version = "1.0" encoding = "utf-8"?> <!doctype hibernate-configuration public " - // hibernate/hibernate構成name = "hibernate.connection.driver_class"> com.mysql.jdbc.driver </property> <property name = "hibernate.connection.url"> jdbc:// localhost:3306/hibernate_one2one_pk1 </propertion name = "hibernate.connection.password"> 1234 </property> <property name = "hibernate.dialect"> org.hibernate.dialect.mysqldialect </property> <マッピングリソース= " resource = "com/src/hibernate/idcard.hbm.xml"> </mapping> </session-factory> </hibernate-configuration>
4。結果を生成します
構成が完了すると、上記のコンテンツから対応するデータベースを生成できます。データベースには、構成されたコンテンツに応じて対応するテーブル構造が生成され、テーブルには対応する外部キーと主キーフィールドがあります。テーブル構造を生成すると、Hibernateは次のように、コンソールに対応するSQLステートメントを出力します。
ALTER TABLE IDCARDドロップ外部キーFK806F76F76ABAC038CD8ドロップテーブルIDCARDドロップテーブルが存在する場合、人が存在する場合はテーブルIDCARDを作成します(null、cardno varchar(255)、プライマリキー(personid))テーブルパーソン(null auto_incremement、personname varchar(255)、primar FK806F76ABAC038CD8(PersonID)、制約FK806F76ABAC038CD8外部キー(PershID)参照者(PersonID)
生成されたテーブル構造は、図に示されているとおりです。
PersonIDプライマリキーは、両方のテーブルで同時に生成され、対応する外部キーでもあります。また、2つのテーブルの主要なキーを同時に制限し、ユニークです。
5。書き込みおよびロードテスト
テーブルを生成した後、テーブルを書き込み、テーブルからデータを読み取り、対応するテストクラスを書き込み、テストではユニットテストを使用し、対応するテスト方法を書き込みます。
5.1書き込みテスト
データベースに書き込むときは、書かれた両方のオブジェクトを対応するトレーニング状態に変換する必要があることに注意してください。そうしないと、状態変換エラーが発生します。テストコードは次のとおりです。
public void testsave1(){session session = null; try {//セッションオブジェクトセッション= hibernateutils.getSession(); //セッショントランザクションsession.begintransaction()を有効にします。 //個人のオブジェクトを作成し、人を保存= new Person(); person.setName( "Zhangsan"); session.save(person); // idcardオブジェクトを作成し、idcard idcard = new idcard()を保存します。 idcard.setcardno( "1111111111111"); idcard.setperson(person); session.save(idcard); //トランザクションを送信し、データベースsession.getTransaction()。commid()を変更します。 } catch(例外e){//エラーメッセージe.printstacktrace(); // business lollback session.getTransaction()。rollback(); }最後に{//セッションを閉じますhebernateutils.closessession(session); }}挿入されたデータを以下に示します。
5.2読み込みテスト
読み込み方法を書きます。協会の関係は双方向であるため、対応する負荷操作は、一方の端、つまり、対応する個人クラスを取得し、対応するIDカード情報を個人クラスから取得することです。逆のことも真実であるはずです。コードは次のとおりです。
public void testload1(){session session = null; try {//セッションオブジェクトセッション= hibernateutils.getSession(); //セッショントランザクションsession.begintransaction()を有効にします。 //人オブジェクトを取得し、person =(person)session.load(person.class、5);を保存します。 System.out.println( "idcard.id:"+person.getIdcard()。getId()); system.out.println( "idcard.cardno:"+person.getIdcard()。getCardno()); // idcardオブジェクトを作成し、idcard idcard =(idcard)session.load(idcard.class、5)を保存します。 system.out.println( "person.id:"+idcard.getPerson()。getId()); system.out.println( "person.name:"+idcard.getPerson()。getName()); //トランザクションを送信し、データベースsession.getTransaction()。commid()を変更します。 } catch(例外e){//エラーメッセージe.printstacktrace(); // business lollback session.getTransaction()。rollback(); }最後に{//セッションを閉じますhebernateutils.closessession(session); }}上記のテスト方法を実行し、次のようにコンソールに関連するコンテンツを印刷します。
2。双方向外部キー関係
双方向外部主要協会は、外国の主要協会の特別なケースとして理解できます。この専門は、主に双方向の対応であるためです。前の記事では、外部キーフィールドをテーブルに追加する場合は、<多くの対象>タグを使用して、関係モデルに対応する外部キー列を生成することができます。双方向外部キー協会を達成する場合は、このタグを使用する必要があります。
1。オブジェクトモデル
まずオブジェクトモデルを見てみましょう。人とIDカードは1対1の関係です。 1人がアイデンティティに対応するため、それらの間の多重は1対1であり、この対応は双方向です。したがって、そのオブジェクトモデルは、下の図に示すように、双方向の一次キーと同じです。
2。リレーショナルモデル
対応する関係モデルは大きく変わります。 1対1の外部キー関係は、テーブルに対応する外部キーを生成します。人とIDカードを取得すると、関係モデルにIDカード番号の主要なキー列があり、下の図に示すように、それらの間に双方向の1対1の状況が形成されることを意味します。
それらの間の対応は、上の図に示されているとおりです。 Person TableにはIDCardテーブルの主要なキーがあり、1対1の外国のキー関連関係を形成し、双方向です。つまり、idcardは人を通じて取得でき、その人はidcardを介して取得することもできます。
PersonオブジェクトとIDCardオブジェクトのコードは、前の記事のオブジェクトコードと同じです。コードにリストされていません。唯一の違いは、マッピングファイルの構成問題です。
3。ファイルのマッピング
idcard.hbm.xmlマッピングファイル。 IDCardテーブルはマッピングのメインテーブルではないため、1対1のマッピングを行う場合、<1-One>タグを使用して構成する必要があり、個人関係モデルの外部キー属性を策定する必要があります。特定のコードは次のとおりです。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! 3.4.0.cr1-> <hibernate-mapping> <class name = "com.src.hibernate.idcard" table = "idcard"> <id name = "id" type = "int"> <generator /> < /id> <プロパティname = "cardno" type = "java.lang.string"> <column " /one> <on> Property-Ref = "idcard"> </on-one> </class> </hibernate-mapping>
person.hbm.xmlマッピングファイル、Person Tableはマッピングのメインテーブルです。 IDCardテーブルを示すために、外部キー属性列をテーブルに追加する必要があります。したがって、ここでは、<多くの1対1>タグを使用して、対応する外部キーをPersonオブジェクトに生成する必要があります。また、一意も使用して、属性が一意であることを示す必要があります。
<?xml version = "1.0"?> <!doctype hibernate-mapping public " - // hibernate/hibernateマッピングDTD 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <! 3.4.0.cr1-> <hibernate-mapping> <class name = "com.src.hibernate.person" table = "person"> <id name = "id" type = "int" column = "personid"> <generator /> < /id> <プロパティname = "name" type = "java.lang.string"> <column name = " />> < column = "idcardno" unique = "true" not-null = "true"> </many-one> </class> </hibernate-mapping>
オブジェクトのマッピングファイル構成が完了し、リレーショナルモデルが生成されます。 SQLステートメントは次のとおりです。
テーブルの人のドロップ外国人キーFK8C768F55794A52CAドロップテーブルIDCARDドロップテーブルが存在する場合、人が存在する場合はテーブルIDCARDを作成します(ID整数nolt null auto_increment、cardno varchar(255)、primary key(id))create the person (personid))Alter Tableの人物の追加インデックスFK8C768F55794A52CA(IDCARDNO)、制約FK8C768F55794A52CA外部キー(IDCARDNO)リファレンスIDCARD(ID)
生成されたSQLステートメントは、最初に作成されたテーブルです。テーブルを作成するとき、主キー列が指定されています。作成が完了した後、2つのテーブルが変更され、外部キー属性を指定して1対1の関係を形成します。
テスト方法を作成し、ユニットテストを採用し、2つのクラスのオブジェクトをロードし、それぞれオブジェクトの一端から別のオブジェクトを取得します
//オブジェクトをロードして、idcardオブジェクトを使用してpersonオブジェクトをロードしますpublic void testload1(){session session = null; try {session = hibernateutils.getSession(); session.begintransaction(); // idcardオブジェクトを取得し、idcard idcard idcard =(idcard)session(idcard.class、1)のオブジェクトに一意に関連付けられている人オブジェクトを取得します。 system.out.println( "person.id ="+idcard.getPerson()。getId()); system.out.println( "idcard.person.name ="+idcard.getPerson()。getName()); // getPersonオブジェクトを取得し、個人オブジェクトに一意に関連付けられているiDcardオブジェクトを取得しますdersenters.load(person.class、1); System.out.println( "idcard.id:"+person.getIdcard()。getId()); system.out.println( "idcard.cardno:"+person.getIdcard()。getCardno()); //トランザクションsession.getTransaction()。commid(); } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{hibernateutils.closessession(session); }}生成されたコンテンツ:
2つのマッピング関係を比較すると、主キーと外部のキーマッピング関係はどちらも双方向マッピング関係であり、マッピング関係をオブジェクトの両端で同時に構成する必要があります。違いは、主キーは属性列を生成する必要がないため、<1対1>のみを使用する必要がありますが、テーブルの主要なキーに外部の主要なキー生成戦略を使用する必要があり、外部キーオブジェクトにマークされている必要があります。外国のキー生成戦略は、<by-to-one>タグを使用して、新しい外部キー列を生成する必要があります。
結論
双方向の関連付けで1対1のマッピングについて説明しました。 2つの記事は、主に双方向の関連付けの2つの用途について説明しています。実際、それはまだ非常に簡単です。外部キーを生成する場合は、<多> 1つのタグを使用することを忘れないでください。一意の場合は、一意の属性を追加します。 <1-One>タグは、1対1の関係のみを示します。 1つのオブジェクトが別のオブジェクトをロードする方法のみを示し、関係モデルに新しい列を追加しません。次の記事では、1対多くの関係について説明します。