Hibernateは分類と統合を実施し、Hibernateが実際にコアオブジェクト、マッピング、およびHQLの3つの部分に分割されていることを発見しました。これらの3つの部分は、開発プロセスで最も一般的に使用されています。前の記事では、コアオブジェクトとオブジェクト間の変換方法について説明します。次に、冬眠のマッピング使用方法について説明します。
Hibernateの重要な機能はマッピングであり、オブジェクトモデルとリレーショナルモデル間を変換できます。オブジェクト指向のプログラミングアイデアによって提唱されています。マッピングプログラムを使用する開発者は、オブジェクトモデルでコードの執筆を気にするだけです。オブジェクトとリレーショナルデータベースの間のマッピングは、通常、XMLドキュメントで定義されます。このマッピングドキュメントは、読みやすくなるように設計されており、手動で変更できます。次の図に示すように、このマッピング関係を要約します。
マッピングはXMLを介して定義され、Hibernateが作成したセッションを使用して管理され、最後にセッションはJTAを使用してデータベースに変更を送信します。セッションは、永続的なレイヤーのオブジェクトを管理する永続性マネージャーとして理解できます。 SessionFactoryによって作成されます。 Hibernateを使用してプログラミングするときは、最初にデータベースに接続する必要があるため、最初にXMLのデータベース接続の構成を確認し、ドキュメントの構成(データベースミラーとして理解できます)の構成に応じてSessionFactoryを作成し、セッションファクターを作成する必要があります。最後に、セッションはデータベースの変更を均一に送信し、すべての操作を完了します。
使用プロセス
1.マッピングファイルを作成すると、マッピングファイルに.hbm.xmlが接尾辞が付けられており、これが冬眠マッピングファイルであることを示します。
2。マッピングファイルにエンティティクラスを登録し、エンティティクラスのプロパティをマッピングクラスに追加します。プロパティを追加するときは、IDとプロパティの2つの値を指定する必要があります。 IDは、それがエンティティの唯一の識別子であることを示し、プロパティはそれがテーブルのフィールド列であることを示します。
3.変更を送信し、データを同期します。
注:データベースにXMLデータを開発した開発者は、このマッピングが実際にバッチアップデートとバッチ作成のプロセスであり、マッピングも例外ではないことをすぐに理解します。 Hibernateは、標準に従って変換できる一連のマッピング標準を規定しています。その内部実装はまだ死んでいるため、比較的柔軟で使いやすいです。
シンプルなエンティティクラスマッピングプロセス:
1。エンティティのプロパティコードクラスユーザー1:
パッケージcom.hibernate; Import Java.util.date; public class user1 {private string id;プライベート文字列名;プライベート文字列パスワード。プライベートデートCreateTime;プライベートデートの有効期間; public string getId(){return id; } public string getname(){return name; } public void setName(string name){this.name = name; } public string getPassWord(){パスワードを返します。 } public void setPassword(string password){this.password = password; } public date getCreatetime(){return createTime; } public void setCreatetime(date createTime){this.createtime = createTime; } public date getExpireTime(){return expiretime; } public void setExpiretime(date expiretime){this.expiretime = expiretime; }}
2。マッピングファイルのuser1.javaのuser1.hbm.xmlの内部コード実装:
基本的なデータベースで設定できる設定も、冬眠で提供されます。ラベル属性を使用して、特定のマッピング関係を設定できます。
クラス - >テーブルは、一般的に使用されるプロパティを使用します。
(1)名前:マップエンティティクラス、その値は、テーブルに変換する必要があるエンティティクラスの名前に設定する必要があります。同期中、対応するエンティティクラスはこの属性に基づいて見つかります。
(2)テーブル:データベーステーブルの名前をマップします。マッピングするテーブルの名前がエンティティクラス名と異なる場合は、このプロパティを使用してマッピングされたテーブルを指定します。存在しない場合、プロパティの値に基づいてテーブルが作成されます。
以下に示すように、上の図の構成によって生成されたテーブル構造を確認してください。
テーブル名はt_user1に変更されます。 IDフィールドはuser_idに変更され、フィールドの長さは32ビットです。 CreateTimeプロパティは、データベースフィールドCreate_Timeにマッピングされ、日付のタイプに変更されます。
プロパティ - >フィールドはIDまたはプロパティタグを使用します。一般的に使用されるプロパティ:
(1)名前:関数はクラスタグの名前に似ており、値はエンティティクラスのマッピング属性名を決定します。
(2)列:マッピングテーブルの列名を指定するエンティティクラスタグのテーブルと同様に、存在しない場合は作成されます。
(3)タイプ:データベース内のフィールドにマッピングされたデータ型を指定し、必要に応じてドキュメントを表示します。
(4)オプションであるジェネレーターは、永続的なクラスの一意の識別子を生成するために使用されます。
<id name = "id" type = "long" column = "cat_id"> <generator> <param name = "table"> uid_table </param> <param name = "column"> next_hi_value_column </param> </generator> </id> </id>
すべてのジェネレーターは、org.hibernate.id.identifiergeneratorインターフェイスを実装します。これは非常にシンプルなインターフェイスです。一部のアプリケーションは、独自の特定の実装を提供することを選択できます。もちろん、Hibernateは多くの組み込みの実装を提供します。一般的に使用されるタイプは次のとおりです。
(1)ID:返された識別子は、長い、短い、またはintです。データベースの自己充填フィールドに似ています。
(2)シーケンス:DB2、PostgreSQL、Oracle、SAP DB、MCKOI、およびジェネレーターでシーケンスを使用します。返された識別子は、長い、短い、またはintのタイプです。データベース全体では、単一のテーブルに自己障害する代わりに、単一のテーブルに自己障害を追加する必要があることを指定する必要があります。
(3)UUID:128ビットUUIDアルゴリズムを使用して、ネットワークで一意の文字列型識別子を生成します(IPアドレスを使用)。 UUIDは、32ビット16進数の文字列としてエンコードされています。 .NETによって生成されたシリアル番号と同様。
(4)ネイティブ:基礎となるデータベースの機能に基づいて、ID、シーケンス、またはHILOのいずれかを選択します。柔軟な方法では、使用されるデータベースに基づいて使用されるIDタイプが決定されます。 MySQLはアイデンティティを選択し、Oracleはシーケンスを選択します。
(5)割り当て:エンティティクラスの識別IDを手動で作成します。これは、<Generator>要素が指定されていない場合のデフォルトの生成ポリシーです。
(6)外国:別の関連するオブジェクト識別子を使用します。通常、<1対1>と組み合わせて使用されます。
開発者は、ドキュメントの指示に従って構成プロパティを書き込むための手動構成方法によく使用されます。これは非常に原始的です。初心者は、思考を助けるために手動構成方法を使用することをお勧めします。視覚的な方法を使用してXML構成ドキュメントを構成および生成する多くのサードパーティツールもあり、開発効率を向上させます。 Xdoclet、Middlegen、Andormdaなどの同様のツール。
連想マッピングは多数です
冬眠の基本マッピングについては上記で説明します。エンティティクラスはテーブルに対応し、対応するHibernateマッピングファイルの<class>タグマッピングを使用します。エンティティクラスの通常のプロパティは、テーブルフィールドに対応し、<property>タグを使用してマッピングされます。さらに、エンティティクラスを構築する場合は、次のように注意する必要があります。パラメーターのないデフォルトのコンストラクターは、エンティティクラスに実装する必要があり、ラベルを提供する必要があります。ファイナルを使用してエンティティクラスを変更し、エンティティクラスのゲッターおよびセッターメソッドを生成しないことをお勧めします。最後に、いくつかの主要な主要な生成戦略が導入され、次のステップは、多くのマッピングについて議論することです。
この多くの相関マッピングは、オブジェクトモデルに反映されています。それは集約関係です。ユーザーはグループの一部です。グループにはユーザーがいます。彼らのライフサイクルは異なり、次の図に反映できます。
では、この多面的な関係マッピングは、冬眠でどのように設定されていますか?以下には、2つの方法が紹介されます。<on-to-one>タグを使用して直接マッピングするか、<on-one> cascadeを使用してテーブルを変更します。
1.多くの直接マッピング<br />それは、それが多くの関係を指すという文字通りの意味から理解することができます。多くはより多くの終わりを指し、1つはより少ない終わりを指します。それを使用すると、タグはより多くの端のHBMでよく使用され、<多くの1対1>の名前属性は、次のようなマッピングファイルの対応するクラスの片方の属性に設定されます。このタグはuser.hbm.xmlに追加されます。これは多くに対応します。タグの名前値はグループ1つであり、user.javaにグループと呼ばれる属性があります。次に、実装を実装する特定のコードクラスを見てみましょう。
(1)user.javaクラスコード。グループと呼ばれるプロパティがあり、<buly-one>の一方の端の名前値として使用されます。
パブリッククラスユーザー{プライベート文字列名; public string getName(){return name; } public void setName(string name){this.name = name; }プライベートグループグループ; Public Group getGroup(){return Group; } public void setGroup(グループグループ){this.group = group; }}(2)user.hbm.xmlの<buly-one>の名前の値は、user.javaのone-sideのプロパティ値です。データベースに新しい列が生成されます。これは、ユーザーテーブルの外部キーとして理解できます。
<?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.hibernate.user" table = "user"> <id name = "id" type = "java.lang.long.long"> <column name = "id" /> <generator />> < /id> <! - 名前の値は、ユーザーのプロパティです。テーブル内の列が自動的に生成されるため、列は列の使用を使用して変更されます。
(3)上記のマッピング関係をテストし、2つのユーザーオブジェクトをテーブルに書き込み、it user1とuser2に名前を付け、zhang san and li siに名前を付け、セッションを使用してオブジェクトを保存し、データベースにデータを書き込みます。コードは次のとおりです。
public void testsave1(){session session = null; try {session = getSession.getSession(); session.begintransaction(); Group Group = new Group(); group.setName( "Power Node"); user user1 = new user(); user1.setName( "Zhang San"); user1.setgroup(group); user user2 = new user(); user2.setname( "li si"); user2.setgroup(group); session.save(user1); session.save(user2); // TransientObjectExceptionエラーが報告されますsession.getTransaction()。commive(); } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{getSession.closessession(session); }}ただし、上記のコードを使用する場合、Writeを実行するときにTransientObjectExceptionが報告されます。これは、ユーザーオブジェクトを保存するときに、<buly-one>に追加されたグループに従ってメモリ内のグループオブジェクトを検索するためです。ただし、上記のコードでは、グループオブジェクトは常に一時的な状態にあり、セッションによって管理されていません。つまり、セッションオブジェクトが見つからず、ユーザーオブジェクトが永続的な状態に入るため、このエラーが報告されます。正しいコードは次のとおりです。
public void testsave2(){session session = null; try {session = getSession.getSession(); session.begintransaction(); Group Group = new Group(); group.setName( "Power Node"); session.save(group); //ここでグループオブジェクトを永続的なオブジェクトに設定しますuser1 = new user(); user1.setName( "Zhang San"); user1.setgroup(group); user user2 = new user(); user2.setname( "li si"); user2.setgroup(group); session.save(user1); session.save(user2); //グループとユーザーは永続的な状態のオブジェクトであるため、データを正しく保存できます// } catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{getSession.closessession(session); }} 2。カスケードマッピング
グループオブジェクトとユーザーオブジェクトの両方を上記の永続オブジェクトに変換することに加えて、Cascade Cascadeマッピング属性を使用して、<buly-One>属性にカスケード属性を追加し、セーブアップデートにコピーすることもできます。グループオブジェクトが永続的な状態にない場合、データベースに書き込むことができます。このようにして、2つのユーザーオブジェクトのグループ属性を同じグループオブジェクトに設定して、多面マッピング関係を実現する必要があります。この時点で、user.hbm.xmlの対応するコンテンツは次のコードです。
<?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.hibernate.user" table = "user"> <id name = "id" type = "java.lang.long"> <column name = "id" /> <generator />> < /id> <! - カスケード修正テーブル - > cascade = "save-update"> </many-one> </class> </hibernate-mapping>
注:Cascadeを保存するように設定された後、データベースの変更、追加、および削除をカスケードすることができますが、特定のCascadeクエリ操作は実行できません。
対応するテスト構成ファイルメソッドは次のとおりです。
// cascade cascade public void testsave3(){session session = null; try {session = getSession.getSession(); session.begintransaction(); Group Group = new Group(); group.setName( "Power Node"); user user1 = new user(); user1.setName( "Zhang San"); user1.setgroup(group); user user2 = new user(); user2.setname( "li si"); user2.setgroup(group); session.save(user1); session.save(user2); // cascadeが使用されるため、transientObjectexceptionはスローされませんでした// hibernateは最初にユーザーの関連するオブジェクトグループを保存します} catch(Exception e){e.printstacktrace(); session.getTransaction()。rollback(); }最後に{getSession.closessession(session); }} 3。比較昇華
2つの方法は、多面マッピング方法も実装しており、結果は同じですが、実装が非常に異なっています。 1つ目か2番目のタイプが<by-to-One>を使用して、タグをマッピングファイルに多くの端に追加し、マッピングファイルによって登録されたクラスの端端の属性値にタグの名前属性を割り当てて、同じです。違いは、直接マッピング関係が冬眠フィールドの属性を使用しないことであり、実装がより柔軟に対応しています。追加、削除、変更をサポートするだけでなく、クエリを許可します。 2番目のカスケードカスケード変更は、冬眠によって提供される方法を採用しています。この方法は、追加、削除、変更のみをサポートし、クエリをサポートしません。