2011-07-22 179 views
7

一個對象的字段我有一個object A映射到table A在DB更新在休眠

class A { 
    Integer id; 
    String field2,field2;field3 ,... fieldN; 
    //lots of other attribute 
} 

現在我想要寫一個DAO API,僅僅更新單個field.One辦法是,我可以第一加載那麼對象改變我需要的屬性,然後使用合併API

//start transcation 
A a = session.load(A.class, id); 
A.setfieldP(newValue) 
session.merge(A) 
//commit transcation 

現在,如果我用下面的代碼

//start transcation 
A a = new A(); 
a.setId(id); //set a id by which object A exists in DB 
A.setfieldP(newValue) 
session.merge(A) 
//commit transaction 

現在第二種方法除id和fieldP之外的所有字段設置爲空

1)現在還有其他方法嗎?
2)我可以使用更新而不是合併?

回答

2

我通常喜歡session.get VS session.load,作爲session.get will return null,而不是拋出一個異常,但它取決於你想要的行爲。

加載對象,設置你的領域,並呼籲無論是

session.merge(myObject) 

是標準的方法,雖然也可以使用

session.saveOrUpdate(myObject) 

只要對象尚未分離,在你的情況下,它不會被分離。 Here is a good article解釋合併和saveOrUpdate的差異。

在你的第二個例子,你正在編輯的對象的主鍵?這通常是不好的形式,您應該刪除並插入而不是更改主鍵。

+0

您可能已經知道這一點,但saveOrUpdate可以處理分離的對象。唯一一次遇到麻煩的時候,是有一個現有的對象具有相同的ID連接到會話。 –

+0

'saveOrUpdate'將更新值的分貝(+1) – bluefoot

+0

@Russ Sanwald現有對象:在第二個方法whati我試圖做的是,我想更新object.Now更新它,我不想取它從數據庫然後更新,而不是我創建一個新的對象A,設置其主鍵和字段N,然後更新。我設置主鍵爲我想用primarykey = X更新對象(假設對象與id x已經目前在數據庫中,我設置fieldN,因爲我想更新它。我不改變主鍵,但我的目的是chnage使用id = X – akshay

13

如果您需要更新大量的實體中的一次最有效的方法是使用一個查詢:

Query query = session.createQuery("update EntityName set fieldP = 'newValue' " 
     + "where id IN (75, 76)"); 
query.executeUpdate(); 

這允許您更改字段值,而無需加載的實體到內存中。

這是最好的做法是使用命名查詢和命名參數 - 上述實施僅僅是一個例子。這裏

+0

這可以被認爲是對這個問題偏離主題。 – bluefoot

+6

我不同意。首先,如果有一個,他會要求採取不同的方法。其次,從他的第二個代碼片段可以清楚地看出,他想避免將實體加載到內存中。 –

0

一個更優化,可以使用動態更新設置爲true的實體。這將確保只要有更新,只有被更改的字段被更新。

+0

是有必要首先從數據庫中,然後獲取對象update.What如果我實例化一個新的對象ID爲X,然後只設置我想更新的領域?在我的方法2個未設置保存爲所有其他領域nulls,我希望它應該保留舊的非空值 – akshay

2

使用JPA,你可以這樣來做。

CriteriaBuilder builder = session.getCriteriaBuilder(); 
CriteriaUpdate<User> criteria = builder.createCriteriaUpdate(User.class); 
Root<User> root = criteria.from(User.class); 
criteria.set(root.get("fname"), user.getName()); 
criteria.set(root.get("lname"), user.getlastName()); 
criteria.where(builder.equal(root.get("id"), user.getId())); 
session.createQuery(criteria).executeUpdate();