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);
4

8 回答 8

3

list.remove方法从列表中删除第一次出现的指定元素。下面的代码块是从ArrayList源代码复制的:

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

它使用该Object.equals方法检查要从列表中删除的对象的相等性。所以你需要重写类中的equals方法Item来判断哪些items是相等的。而且当你覆盖时equals(),你总是需要覆盖,hashCode()所以这两种方法是一致的

Item现在,当传递一个从 中删除的实例时list,您需要设置Item用于实现该equals方法的所有属性的值。

但是你不应该使用database identifier (id)来实现equals(). 在保存实体之前,Hibernate 不会分配标识符值。Set因此,如果在保存之前将对象添加到 a中,则它的哈希码会在它包含在 中时更改(在保存操作时),这Setjava.util.Set. 您可以使用属性组合,这对于Item.

于 2013-10-22T03:21:05.297 回答
1

在删除之前加载项目对象。

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

然后打电话

basket.getItems.remove(item);
于 2013-12-02T09:49:18.940 回答
1

有几种方法,如果您对 hql 或 sql 感到满意,我更喜欢使用查询,

  1. 方法一

    从 id in (x,y,z,xy...) 的表中删除;

优点:您无需从数据库中加载任何内容。您只需运行一个 sql 并获得响应。

  1. 方法二

渴望将对象获取到内存中(Ofcoz,从客户端发送 ID)迭代项目列表并匹配 ID 并将其删除。刷新会话。

于 2013-12-05T20:21:27.277 回答
0

您不能将您的 ArrayList 更改为 HashMap 并将对象存储在其 ID 上吗?然后你可以用一行代码删除它们。

于 2013-12-05T12:52:38.480 回答
0

简单明了

不要删除副本,在里面搜索:

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

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

但是,value="${item}"如果您没有覆盖item.toString().

于 2013-12-05T08:07:21.483 回答
0

不要直接渲染对象。不要这样做。那就是痛苦和疯狂。假设您这样做,并且没有覆盖toString()

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

然后发生以下情况:

  • 您将项目获取到 中List,并使用 的默认class.name@address实现来呈现每个项目toString()
  • 用户选择一些要删除的项目并提交表单,这会发出一个新的 HTTP 请求。物品的原件List不见了,所以那些地址指向……嗯,你不知道它们指向什么。

(还有其他问题:如果恶意攻击者检查页面源,他们现在知道您正在运行基于 Java 的服务器。没有理由自愿提供这些信息。)

现在,您可能会想“嘿,我将这些项目放在我的会话中”。现在您遇到了同样的问题:大多数会话处理实现将在将项目存储在会话中时将它们序列化,并在检索时将它们反序列化为新副本。您的对象引用现在毫无意义。

你可以覆盖toString(),但为什么呢?只需在删除查询中传递 ID 并将它们发送到您的数据库。这样,如果有人决定更改toString()实现,就不会感到意外。

于 2013-12-05T23:54:31.500 回答
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.

override equals() and toString() methods我几乎总是model classes

于 2013-12-03T09:08:42.450 回答
0

Hql。

session.createQuery("delete from Item i where i.id in (:iids)").setParameter("iids", item_ids).executeUpdate();
于 2013-12-05T16:51:43.697 回答