1. 程式人生 > 其它 >Java中使用Hibernate系列之對映關聯啟動工作學習(第五節)

Java中使用Hibernate系列之對映關聯啟動工作學習(第五節)

前面一節我們建好了對映檔案,現在我們把people和events 一起放到EventManager的新方法中統一管理:

private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = (Event) session.load(Event.class, eventId);
aPerson.getEvents().add(anEvent);
session.getTransaction().commit();
}

在載入一Person和Event後,使用普通的集合方法就可容易地修改我們定義的集合,Hibernate會自動檢測到集合已經被修改並需要更新回資料庫,這叫做自動髒檢查(automatic dirty checking),你也可以嘗試修改任何物件的name或者date屬性,只要他們處於持久化狀態,也就是被繫結到某個Hibernate 的Session上,Hibernate監視任何改變並在後臺隱式寫的方式執行SQL。

網路配圖

同步記憶體狀態和資料庫的過程,通常只在單元操作結束的時候發生,稱此過程為清理快取(flushing),在我們的程式碼中,工作單元由資料庫事務的提交(或者回滾)來結束——這是由CurrentSessionContext類的thread配置選項定義的。

當然,你也可以在不同的單元操作裡面載入person和event,或在Session以外修改不是處在持久化(persistent)狀態下的物件,還可以在一個集合被脫管時修改它:

private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person aPerson = (Person) session
.createQuery("select p from Person p left join fetch p.events where p.id = :pid")
.setParameter("pid", personId)
.uniqueResult();
Event anEvent = (Event) session.load(Event.class, eventId);
session.getTransaction().commit();
aPerson.getEvents().add(anEvent);
Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(aPerson);
session2.getTransaction().commit();
}

對update的呼叫使一個脫管物件重新持久化,你可以說它被繫結到一個新的單元操作上,所以在脫管狀態下對它所做的任何修改都會被儲存到資料庫裡,這也包括你對這個實體物件的集合所作的任何改動(增加/刪除)。 這對我們當前的情形不是很有用,但它是非常重要的概念,你可以把它融入到你自己的應用程式設計中,在EventManager的main方法中新增一個新的動作,並從命令列執行它來完成我們所做的練習,如果你需要person及event的識別符號 — 那就用save()方法返回它,程式碼如下:

else if (args[0].equals("addpersontoevent")) {
Long eventId = mgr.createAndStoreEvent("My Event", new Date());
Long personId = mgr.createAndStorePerson("Foo", "Bar");
mgr.addPersonToEvent(personId, eventId);
System.out.println("Added person " + personId + " to event " + eventId);
}

我們可以自己設計一個值型別的集合,這在概念上與引用其它實體的集合有很大的不同。

好了,這一節的學習先到這裡,後面章節中會繼續學習Hibernate。我們學習方式是每一節學習一個知識點(每天花10分鐘學習)。