1

名前のリストがあります:List<Name>Nameは、次の 2 つのメソッドがあります。

  • toString()「名前: トム」を返します
  • getName()「トム」を返します

特定の名前を持つ人物をデータベースに照会するには、次のようにします。

// Query a single database entry
Query query = em.createQuery("FROM person WHERE name = :name");
query.setParameter("name", names.get(0).getName());

複数のエントリを照会したい場合 (これを使用して、次のWHERE ... IN (...)ことを行う必要があります。

// Convert the list of name instances to a list of strings
List<String> nameStrings = new ArrayList<String>(names.size());
for (Name name : names) {
  nameStrings.add(name.getName());
}

// Query multiple database entries
Query query = em.createQuery("FROM person WHERE name in (:name)");
query.setParameter("name", nameStrings); // JPA
query.setParameterList("name", nameStrings); // Hibernate

2 番目のリストを作成する必要がありますか? 私はむしろこれをしたい:

// Query a single database entry
Query query = em.createQuery("FROM person WHERE name = :name");
query.setParameter("name", names.get(0));

// Query for multiple database entries
Query query = em.createQuery("FROM person WHERE name in (:name)");
query.setParameter("name", names); // JPA
query.setParameterList("name", names); // Hibernate
4

1 に答える 1

1

簡単な答えは「はい」です。2 番目のリストを作成する必要があります。Listのを提供する必要がありますString(またはむしろCollection) List<Name>。これは決して一致しません。List<Name>名前の を受け取り、 を返す何らかのユーティリティ メソッドを作成することをお勧めしList<String>ます。

public static List<String> toNameStrings(List<Name> names) {
    List<String> list = new ArrayList<String>(names.size());
    for (Name name : names) {
        list.add(name.getName());
    }
    return list;
}

私は以下をテストすることができませんでした。また、どのような方法でも推奨したいのかどうかはわかりませんが、状態に応じて異なるオブジェクト タイプを返す実装を作成できると思います。これを使用すると、として使用するListようなことを行うことができます(ジェネリックはこの段階で窓の外に出ていますが、それらはすべて として返されます)、次にとして使用します。次のようになります。list.setStringMode(false)List<Name>Objectlist.setStringMode(true)List<String>

public class NameAndStringList extends ArrayList<Object> implements List<Object>
{
    private boolean stringMode = false;

    @Override
    public boolean add(Object object)
    {
        return super.add(toName(object));
    }

    // Do the same for add(index, element)
    // Do the same for set(index, element)
    // Do the same for remove(object)

    @Override
    public boolean addAll(Collection<? extends Object> collection)
    {
        final List<Name> convertedCollection = new ArrayList<Name>();
        for (Object object : collection)
        {
            convertedCollection.add(toName(object));
        }
        return super.addAll(convertedCollection);
    }

    // Do the same for addAll(index, collection)
    // Do the same for removeAll(index, collection)
    // Do the same for retainAll(index, collection)

    @Override
    public boolean contains(Object o)
    {
        return super.contains(toName(o));
    }

    // Do the same for containsAll(collection)
    // Do the same for indexOf(object)
    // Implement Iterator that checks the stringMode variable before returning value.
    // Override all iterator methods to retrieve custom Iterator implementation.
    // Override subList(fromIndex, toIndex) to make subList be an instance of NameAndStringList as well.

    @Override
    public Object get(int index)
    {
        if (stringMode)
        {
            return ((Name) super.get(index)).getName();
        }
        return super.get(index);
    }

    // Implement setStringMode(boolean)

    protected Object toNameString(Object object)
    {
        if (object instanceof Name)
        {
            // Convert to String here
        }
        return object;
    }

    protected Name toName(Object object)
    {
        if (object instanceof String)
        {
            // Convert to Name here.
        }
        return object;
    }
}

これは、aStringを a に、またはその逆に変換できることに依存していますが、インスタンスNameを使用して常に自分で入力することがわかっている場合は、常にそのビットを取り除くことができます。Nameここでの一般的な考え方は、ListストアNameインスタンスですがStringList<Object>. 繰り返しますが、このアプローチをお勧めするかどうかはわかりませんが、要件を満たすか、少なくとも atm を得ることができる限り近いものにする必要があります。

于 2012-08-22T09:01:10.943 に答える