hibernate 5(8)操作オブジェクト入門[3]操作オブジェクトパッケージ方法


なぜ「パッケージング方法」と言うのでしょうか?下位レベルの削除変更操作をカプセル化してくれるので、対応する方法を直接呼び出すと、データベースデータを柔軟に操作できます.これらはSessionインタフェースによって提供されています.次に、これらの方法をインスタンスごとに分析します.
1.saveメソッド
Sessionのsave()メソッドは、一時オブジェクトを永続化オブジェクトSessionのsave()メソッドに変換して、次の操作を完了します:1.SessionキャッシュにUserオブジェクトを追加して永続化する.マッピングファイルで指定した識別子ジェネレータを選択して、永続化オブジェクトに一意のOIDを割り当てます.プロキシプライマリキーを使用している場合、setId()メソッドでUserオブジェクトにOIDを設定するのは無効です.3.flushキャッシュ時にinsert文を実行する計画です.
注意:1.Hibernateは、オブジェクトのOIDを永続化することによって、データベース関連レコードとの対応関係を維持します.Userオブジェクトが永続化状態にある場合、プログラムが勝手にIDを変更することは許されない.そうしないと、異常を報告する.org.hibernate.HibernateException: identifier of an instance of com.zeng2.model.User was altered from 17(永続化状態の元の値)to 100(新しく変更する値)です.したがって、実際の開発ではsetId()をprivateに設定してユーザーがエンティティid 2を変更することを防止する必要があります.永続化オブジェクトの初期化が一般的に完了した場合、saveメソッドを呼び出す前に、リソースの準備(メンバー属性値の設定)を完了してから呼び出します.そうしないと、次のように追加のsql文が追加されます.
//      
User user1 = new User();
user1.setName("name1");
session.save(user1);
//Hibernate: insert into t_user2 (name, id) values (?, ?)
//      
User user2 = new User();
session.save(user2);
user2.setName("name2");
//Hibernate: insert into t_user2 (name, id) values (?, ?)
//Hibernate: update t_user2 set name=? where id=? update t_user2 set name=? where id=?

2.persistメソッド
persistとsaveは、オブジェクトを永続化するために使用できますが、userとは異なり、OIDがNullでないオブジェクトに対してsave()メソッドを実行すると、そのオブジェクトが新しいoidでデータベースに保存されます.しかしpersist()メソッドを実行すると例外が放出されます.
//  persist save   
User user = new User();
user.setId(100);
session.save(user);
//  Hibernate: insert into t_user2 (name, id) values (?, ?)
User user2 = new User();
user2.setId(200);
session.persist(user2);
//   org.hibernate.PersistentObjectException: detached entity passed to persist: com.zeng2.model.User

3.getとloadの方法
  • 同じ点:固定OIDに従ってデータベースから永続化オブジェクト
  • をロードすることができる.
  • の違い:
  • データベースにOIDに対応するレコードが存在しない場合、load()メソッドはObjectNotFoundException異常を放出し、get()メソッドはnullを返す.
  • の両方は、対応するオブジェクトの取得ポリシーをインスタントロードに設定しない限り、loadはデフォルトで怠惰ロードポリシーを使用します.getは呼び出しさえすれば、すぐにデータベースからデータを甲にします.


  • 4.updateメソッド
    遊離オブジェクトを永続化オブジェクトに変換し、flush時にupdate文を実行する計画です.使用すると例外が放出されます.1.update()メソッドが遊離オブジェクトを関連付ける場合、Sessionのキャッシュに同じOIDの永続化オブジェクトが既に存在する場合、例外2が放出される.update()メソッドが遊離オブジェクトを関連付ける場合、データベースに対応するレコードが存在しない場合、例外も放出される.次はテストコードです.
    //  update
    User user = new User();
    session.update(user);
    //   :org.hibernate.TransientObjectException: The given object has a null identifier: com.zeng2.model.User
    User user = new User();
    user.setId(1);//       id
    session.update(user);
    //Hibernate: update t_user2 set name=? where id=?
    User user = new User();
    user.setId(111111);//        id
    session.update(user);
    //   :org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    User user = session.get(User.class, 1);
    User user2 = new User();
    user2.setId(1);
    session.update(user2);//     session         
    //   :org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.zeng2.model.User#1]

    5.saveOrUpdateメソッド
    SessionのsaveOrUpdate()はsaveとupdateの統合と見なすことができ,両者は有効な相補を形成する.その実行手順は次の図に示されています.
    Created with Raphaël 2.1.0 saveOrUpdateオブジェクトフリーオブジェクト(yes)、一時オブジェクト(no)更新オブジェクト保存オブジェクトyes no
    idがnullであるか否かに基づいて、オブジェクトの状態を判断することがよくあります.次に、テスト例を見てみましょう.
    //  saveOrUpdate
    //1.     
    User user = new User();
    session.saveOrUpdate(user);
    //Hibernate: insert into t_user2 (name, id) values (?, ?)
    //2.   id       
    User user = new User();
    user.setId(1);//      id    
    session.saveOrUpdate(user);
    //Hibernate: update t_user2 set name=? where id=?
    //3.   id,        ,    
    User user = new User();
    user.setId(111111);//       id    
    session.saveOrUpdate(user);
    //org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

    6.mergeメソッド
    遊離オブジェクトの属性を永続化オブジェクトにコピーする.まず、テストコードを見てみましょう.
            //     update        Session      id   1   
    // User user = session.get(User.class, 1);
    // User user2 = new User();
    // user2.setId(1);
    // session.update(user2);
            //   :org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session : [com.zeng2.model.User#1]
    
            //  merge
            User user = session.get(User.class, 1);
            System.out.println(user3.getName());//name
            User user2 = new User();
            user2.setId(1);
            user2.setName("newName");
            session.merge(user2);
            System.out.println(user3.getName());//newName
            System.out.println(user == user2);//false
            System.out.println(user2 == user3);//false
            System.out.println(user3 == user);//true
            //Hibernate: update t_user2 set name=? where id=?
            /*     ,      : +----+---------+ | id | name | +----+---------+ | 1 | newName | */

    以上から、sessionに特定のidのオブジェクトが存在する場合、同じidのオブジェクトを自分で偽造しupdateで永続化しようとすると、エラーが発生することがわかる.mergeを使用すると、正常に更新されます.次に、この例と組み合わせて、mergeメソッドを呼び出す実行プロセスを分析します.
    1.user 2が遊離オブジェクトである場合(idはnullではない)
  • は、まずセッションキャッシュにIDとuser 2が同じUserを検索する、(userが見つかった)場合、user 2の値をuserにコピーし、flush時にupdate文を実行するが、ここから見ると、更新を操作する理由である.まだ終了していない場合、userの参照(この場合、userの値はuser 2のコピーが完了した値)も返されるので、印刷時にuser 3が使用する.getName=newName、user 3==user
  • セッションキャッシュに見つからない場合は、データベースに同じレコードがあるかどうかを問い合せます.
  • が存在する場合、取得(オブジェクトが永続化されていない場合はoUserに設定)し、user 2のプロパティをoUserにコピーし、oUserの参照をuser 3に返し、flush時にupdate文更新データベース
  • を実行する計画である.
  • が存在しない場合、新しいオブジェクト(nUserに設定)が作成され、user 2のプロパティがこのnUserにコピーされ、saveメソッドがnUserを永続化するように呼び出され、nUserの参照が返されます.このときnUser==user 3はtrue
  • です.

    2.user 2が一時オブジェクトである場合(idはnull)
    新しいオブジェクト(nUserに設定)を作成し、user 2のプロパティをこのnUserにコピーし、saveメソッドを呼び出してnUserを永続化し、nUserの参照を返します.nUser==user 3がtrueです.
    このプロセス分析によると、全過程において、私たちのuser 2は常に非持続的なオブジェクトである.updateを用いるのではなく、メソッド呼び出しが成功すると、必ず永続化オブジェクトとなる.次に、プロセス実行ブロック図を示します.
    7.deleteメソッド
    Sessionのdelete()メソッドは、遊離オブジェクトを削除することも、永続化オブジェクトSessionのdelete()メソッド処理プロセスを削除することもできます:1.計画はdelete文(flushで正式に実行)を実行し、Sessionキャッシュからオブジェクトを削除し、そのオブジェクトは削除状態に入ります.2.Hibernateのcfg.xmlプロファイルにhibernateがあります.use_identifier_rollbackプロパティ、デフォルト値false、trueに設定するとdelete()メソッドの動作が変更されます.delete()メソッドは、永続化オブジェクトまたは遊離オブジェクトのOIDをnullに設定し、一時オブジェクトにします.このようにプログラムはこれらのオブジェクトを再利用することができます
    参照先:http://www.myexception.cn/software-architecture-design/1996251.html