1

我正在寻找一种算法,它将以最有效的方式更新我定期拥有的 Java 对象列表。该算法需要...

当前集

A, B, C

调用重载指令并从数据库返回一个新集合

A, C, D

(即A&C应该更新(如有必要),B需要删除 &D是新的,应该创建)

显然,我可以杀死所有对象并每次重新创建所有对象,但我想避免杀死任何未更改的对象(即,如果数据库中的A&C没有更改,那么当前的 Java A&C对象应该单独继续以他们目前的形式)。

我需要有一个好的算法来执行这些各种检查,然后根据需要添加/更新/删除。我的情况的逻辑应该能够从一个简单的例子中继承下来,我ArrayList<String>认为显然我的A//对象要复杂得多。BC

4

4 回答 4

1

您需要HashMap以数据库 ID 作为键,将完整对象作为值。您将遍历结果集,并通过 O(1) 操作找出该项目是否已经存在。然后,您可以根据需要添加和更新。在您继续进行时,为所有获取的条目构建一个临时HashSet的数据库键。然后进行最终设置差异以从运行时副本中找到要删除的项目。

于 2013-01-02T10:30:03.317 回答
0

您可以有 2 个列表,一个用于 BusinessLayer,另一个用于 UI 层,并相应地标记对象以进行创建/更新/删除。一旦识别出这个标记列表,就可以转发相应的数据库查询。

于 2013-01-02T10:29:30.693 回答
0

我建议你应该为你的集合使用地图。这将使查找更有效。

您可以执行几个循环来找出发生了什么变化。

Map<MyKey, MyType> previous = ..
Map<MyKey, MyType> current = ..

for(Map<MyKey, MyType> entry: current.entrySet()) {
  MyType t = entry.getValue();
  MyType p = previous.get(entry.getKey());
  if (p == null)
      added(t);
  else if (!p.equals(t))
      updated(p, t);
}
for(Map<MyKey, MyType> entry: previous.entrySet()) {
  if(!current.contains(entry.getKey()))
     removed(entry.getValue());
}
于 2013-01-02T10:30:46.063 回答
0

解决方案 1

您的对象可以从基本类型继承,例如:

abstract class PersistentObject {
    private boolean persistent;  // true if exists in database
    private boolean modified;    // true if modified
    private boolean deleted;     // true if deleted

    public boolean isPersistent() { return persistent; }
    protected void setPersistent() { persistent = true; }

    public boolean isModified() { return modified; }
    protected void setModified() { modified = true; }

    public boolean isDeleted() { return deleted; }
    protected void setDeleted() { deleted = true; }
}

并在操作对象时调用/更改对象的状态。例如 :

public void setSomeIntvalue(int value) {
    this.value = value;

    setModified();
}

当您提交更改(迭代您的集合)时,您会DELETE从数据库中删除任何已删除的对象,然后将其从集合中删除。如果isPersistent()是假的,你创建一个新的,如果isModified()是真的,你UPDATE它,否则你什么都不做。

解决方案 2

你可以有一个包装器来管理你的对象集。就像是 :

abstract class AbstractEntitySet<E> {
    private HashSet<E> createdSet = new HashSet<E>();
    private HashSet<E> modifiedSet = new HashSet<E>();
    private HashSet<E> deletedSet = new HashSet<E>();

    public void add(E e) {
        add(e, false);
    }

    public void add(E e, boolean modified) {
        if (modified) {
            createdSet.remove(e);
            modifiedSet.add(e);
            deletedSet.remove(e);
        } else {
            createdSet.add(e);
            modifiedSet.remove(e);
            deletedSet.remove(e);
        }
    }

    public void remove(E e) {
        createdSet.remove(e);
        modifiedSet.remove(e);
        deletedSet.add(e);
    }

    public void applyChanges() {
        for (E e : createdSet) {
            createEntity(e);
        }
        createdSet.clear();

        for (E e : modifiedSet) {
            updateEntity(e);
        }
        modifiedSet.clear();

        for (E e : deletedSet) {
            deleteEntity(e);
        }
        deletedSet.clear();
    }

    protected abstract void createEntity(E e);
    protected abstract void updateEntity(E e);
    protected abstract void deleteEntity(E e);
}

您甚至可以将此集合直接绑定到您的对象:

abstract class BaseEntity<E> {
    private AbstractEntitySet<E> connectedSet;

    @SuppressWarnings("unchecked")
    public E bindTo(AbstractEntitySet<E> set) {
        connectedSet = set;
        return (E) this;
    }

    @SuppressWarnings("unchecked")
    public void setCreated() { connectedSet.add((E) this, false); }
    @SuppressWarnings("unchecked")
    public void setModified() { connectedSet.add((E) this, true); }
    @SuppressWarnings("unchecked")
    public void setDeleted() { connectedSet.remove((E) this); }
}

您将在哪里声明您的对象(例如):

class SomeObject extends BaseEntity<SomeObject> { 
    public void setSomeThing(...) {
        ...
        setModified();
    }
}

并创建新实例,例如

AbstractEntitySet<SomeObject> entitySet = ...;
...
SomeObject obj = new SomeObject().bindTo(entitySet);

然后更新您的对象,并应用所有更改,例如

obj.setSomeThing(...);
...
entitySet.applyChanges();

解决方案 3

您还可以在应用程序中使用现有的持久层,例如HibernateJPA

于 2013-01-02T10:34:59.863 回答