《我的 O/R Mapping 之旅》勘誤及補充

《我的 O/R Mapping 之旅(二)》,有一段對 People.hbm.xml 的分析,談到爲什麼使用 inverse=”true”:

在車輛管理系統中,代表着一個擁有者擁有多臺車輛。以 java.util.Set 類型表示。 inverse 用於標識雙向關聯中的被動方一端。inverse=false 的一方(主控方)負責維護關聯關係;在車輛管理系統中, AutoInfo 作爲主控方,應該把它設爲“true”。這就好比你(被動方 one)在某個聚會上散發了許多名片,但是有可能你不清楚接收者(主動方 many)的具體背景;這個不要緊,接收者在必要的時候會和你聯繫就是了(主動維護關係)。

紅色標識的句子容易讓人產生歧異,好像是在說把 AtuoInfo 設置成“true”了。應改爲:

在車輛管理系統中,AtuoInfo 作爲主控方,應該在 People 中設置 inverse =“true”。

沿着思路往下走,你也許會問:什麼才叫“主動維護關係”?不妨看看下面的代碼(摘自《我的 O/R Mapping 之旅(三)》):

AutoInfo ai=new AutoInfo();
People people=new People();
public void DoTest() {
   try {
      Configuration cfg = new Configuration().configure();
      SessionFactory sessions = cfg.buildSessionFactory();
      Session session = sessions.openSession();
      Transaction tx = session.beginTransaction();
   
      ai.setLicensePlate("A00001");
      ai.setOwnerNo(people);
      people.setAddress("中國");
      people.setName("張三");
      people.addToAutoInfoSet(ai);
      session.save(people);
      tx.commit();
      session.close();
   } catch (Exception e) {
      System.out.println(e);
   }
}


把“ai.setOwnerNo(people)”註解了試試,由於 AutoInfo 沒有主動維護關係,導致 AUTO_INFO 表中 OWNER_NO 字段爲“Null”。自然 AutoInfo 與 Poople 就不存在任何聯繫了。

人類的求知慾很強烈!
爲什麼非要用 AutoInfo 作爲主控方?People 作主控方不行?好吧,爲 People.hbm.xml 刪除inverse=”true”,再運行以上程序,其實也能保存,只是多了一條SQL:“update auto_info set OWNER_NO=? where AUTO_ID=?”,這就是 AutoInfo 被動地修改和 People 的聯繫。多執行一次 SQL 意味着多了一些開銷,這是對性能不利的!


《我的 O/R Mapping 之旅(三)》,有一段對張三第二次買車的程序和描述:

 AutoInfo ai = new AutoInfo();
 People people = new People();
 public void DoTest() {
  try {
      Configuration cfg = new Configuration().configure();
      SessionFactory sessions = cfg.buildSessionFactory();
      Session session = sessions.openSession();
      Transaction tx = session.beginTransaction();
      people =
       (People) session
        .find(
         "from People where OWNER_ID=1")
        .get(0);
      ai.setLicensePlate("A00002");
      ai.setOwnerNo(people);
      people.getAutoInfoSet().add(ai);
      session.save(people);
      tx.commit();
      session.close();
  } catch (Exception e) {
      System.out.println(e);
  }
}

到這裏,也許你會有這樣的想法:“應該可以直接向 AUTO_INFO 表插入記錄,不通過 People 對象中轉,像寫 SQL 一樣 Easy。” 錯了!以前直接寫 SQL 是可以辦到的,不過現在我們用的可是 Hibernate ,一切都要以對象行事,看見 ai.setOwnerNo(people) 了嗎?傳入參數是個 People 對象實例,不是簡單的字段喔。

這段解釋太絕對了,事實上可以直接保存 AutoInfo 對象,而不用通過保存 People 來中轉:

AutoInfo ai = new AutoInfo();
People people = new People();
public void DoTest() {
  try {
      Configuration cfg = new Configuration().configure();
      SessionFactory sessions = cfg.buildSessionFactory();
      Session session = sessions.openSession();
      Transaction tx = session.beginTransaction();
      people =
       (People) session
        .find(
         "from People where OWNER_ID=1")
        .get(0);
      ai.setLicensePlate("A00002");
      ai.setOwnerNo(people);
      session.save(ai);
      tx.commit();
      session.close();
  } catch (Exception e) {
      System.out.println(e);
  }
}



《我的 O/R Mapping 之旅(四)》,刪除 PEOPLE 表及其關聯的 AUTO_INFO 表時,程序是沒有錯,不過有更簡單的辦法來刪除:

  try {
   Configuration cfg = new Configuration().configure();
   SessionFactory sessions = cfg.buildSessionFactory();
   Session session = sessions.openSession();
   Transaction tx = session.beginTransaction();
   session.delete("from People where OWNER_ID=1");
   tx.commit();
   session.close();
  } catch (Exception e) {
   System.out.println(e);
  }

Hibernate 中,要完成一次操作,可以有多種實現方式,哪種最好,就要靠自己定奪了。


(請注意!引用、轉貼本文應註明原作者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章