2013-10-22 28 views
4

用戶將選擇要從列表中刪除的項目。無法發送項目列表以將其從列表中刪除

我有兩個選擇,要麼傳遞所選項目的ID或其對象的地址在內存中。

第一個問題是,發送選定項目的對象而不是它們的ID是否是正確的方法?

<input type="checkbox" name="selectedItems" value="${item}"/> 

    rather than 

    <input type="checkbox" name="selectedItems" value="${item.id}"/> 

如果我要送物品的ID,當我通過自己的ID,創建一個對象,並設置我無法從列表中,什麼最好的辦法刪除它們的ID?

 Item item = new Item(); 
     item.setID(selectedItems.get(0)); 

     Basket basket = (Basket) session.get(Basket.class, Long.parseLong(basket_id)); 
     basket.getItems.remove(item); <<I cant remove them by just setting their ids!! 

     session.update(basket); 

回答

3

list.remove方法從列表中刪除第一次出現的指定元素。下面的代碼塊從ArrayList源代碼複製:

for (int index = 0; index < size; index++) 
       if (o.equals(elementData[index])) { 
        // REMOVE ITEM FROM THE LIST 
       } 
} 

它使用Object.equals方法來檢查物體的同等爲從列表中刪除。因此,您需要覆蓋Item類中的equals方法,以確定哪個所有items都相等。而當你重寫equals(),你總是需要還覆蓋hashCode()所以這兩種方法是一致的

現在通過一個實例時的Itemlist刪除,您需要設置那名的Item所有屬性的值用於實施equals方法。

但是,您不應該使用database identifier (id)來執行equals()。直到一個實體被保存後,Hibernate纔會分配標識符值。因此,如果在保存之前將對象添加到Set,那麼其散列代碼在Set包含的時候發生更改(保存操作時),與合同java.util.Set相反。您可以使用各個屬性的組合,這對Item的每個實例都是唯一的。

+0

謝謝,實體已經存在於數據庫中,我需要刪除那些用戶選擇的。這是否意味着如果選擇了10個不同的項目,我必須檢索所有這些項目的字段,然後在所有項目上執行相同的方法? – J888

+0

您不必從數據庫中檢索它們。你需要用用戶提交的數據創建10個項目,設置'equals'所需的屬性並將它們傳遞給'basket.getItems.remove(item);'從'list'中移除。現在你可以用'session'更新'basket'。更新(籃法);'。 –

+0

通過從數據庫中獲取它們我的意思是所有的籃子項目,session.get(Basket.class,12),我應該傳遞對象還是僅僅傳遞ID? id可以用來比較,因爲它與我在db中的相同,所以爲什麼我應該接收所有的數據?這是否意味着我應該使用該對象? (第一種方法?)_ – J888

1

刪除前加載項目對象。

Item item = session.load(Item.class, selectedItems.get(0)) 

然後調用

basket.getItems.remove(item); 
0

你的類中的被刪除的對象,你需要override equals() method。代碼它是這樣一種方式,if all member variables are equal, then the objects are equal。 Netbeans IDE中提供了一些模板實現,它們使用一些更多的檢查,例如檢查實例。

Otherwise object member variables could all be same but still objects 
will not be equal since they refer to different locations in memory heap. 

我幾乎是我model classes

0

簡單的總是override equals() and toString() methods和strightforward

不要刪除副本,裏面搜索:

for(Iterator<Item> iterator = basket.getItems().iterator(); iterator.hasNext();) 
{ 
    Item currentItem = iterator.next(); 

    if(selectedItems.contains(currentItem.getId())) 
    { 
     iterator.remove(); 
    } 
} 

但是,切勿使用value="${item}"如果你還沒有重寫item.toString()

0

難道你不能改變你的ArrayList到一個HashMap並存儲對象的ID?那麼你可以用一行代碼去除它們。

0

Hql。

session.createQuery("delete from Item i where i.id in (:iids)").setParameter("iids", item_ids).executeUpdate(); 
1

有幾種方法,如果你習慣使用HQL或SQL,我寧願與查詢做,

  1. 方法的一個

    從表中刪除其中id在(X ,Y,Z,XY ...);

優點:您不需要從數據庫中加載任何東西。你只需運行一個sql並獲得響應。

  1. 方法有兩個

伊格取對象到存儲器(Ofcoz,發送來自客戶端的ID)的迭代的項目的列表和匹配ID和刪除它。刷新會話。

0

不要直接渲染對象。不要這樣做。這種方式是痛苦和瘋狂。假如你這樣做,並沒有覆蓋toString()

<input type="checkbox" name="selectedItems" value="${item}"/> 

然後會發生以下情況:

  • 你獲取了項目成List,使用默認[email protected]實施toString()呈現每個。
  • 用戶選擇一些項目刪除並提交表格,,它會產生一個新的HTTP請求。項目的原始List已經消失,所以這些地址指向...呃,你不知道他們指向了什麼。

(還有其他的問題:如果惡意攻擊者檢查網頁的源文件,他們現在知道你正在運行一個基於Java的服務器沒有理由志願信息)

現在,你可能想一些像「嘿,我只是把這些項目放在我的會話中。」現在你遇到了同樣的問題:大多數會話處理實現會在將它們存儲在會話中時序列化這些項目,並且在檢索時將它們反序列化爲的新副本。你的對象引用現在什麼都沒有。

您可以覆蓋toString(),但爲什麼?只需傳遞ID並將它們發送到刪除查詢中的數據庫即可。這樣,如果有人決定更改toString()實現,則不會有任何意外。