2009/05/09

Creating, Getting and Deleting Data

つづき

キーも良くわからんなぁ。

Creating, Getting and Deleting Data

Saving a JDO data object to the datastore is a simple matter of calling the makePersistent() method of the PersistenceManager instance. The App Engine JDO implementation uses the primary key field of the object to keep track of which datastore entity corresponds with the data object, and can generate keys for new objects automatically. You can use keys to retrieve entities quickly, and you can construct keys from known values (such as account IDs).

JDOデータオブジェクトをDatastoreに保存するには、単純にPersistenceManagerインスタンスの makePersistent()メソッドを呼ぶだけです。App Engine JDO実装はデータオブジェクトと、対応するDatastoreのエンティティを記録するために、そのオブジェクトのプライマリキーのフィールドを利用します。新しいオブジェクトの場合、自動的にキーを生成することができます。エンティティをすばやく取得するためにキーを利用することができ、(アカウントのIDなど)既知の値からキーを生成することもできます。

Making Objects Persistent

To store a simple data object in the datastore, you call the PersistenceManager's makePersistent() method, passing it the instance.

データオブジェクトをDatastoreに保存するには、そのインスタンスを渡して、PersistenceManagerの makePersistent()を呼んでください。

        PersistenceManager pm = PMF.get().getPersistenceManager();

        Employee e = new Employee("Alfred", "Smith", new Date());

        try {
            pm.makePersistent(e);
        } finally {
            pm.close();
        }

The call to makePersistent() is synchronous, and doesn't return until the object is saved and indexes are updated.

makePersistent()の呼び出しは同期的で、オブジェクトが保存されインデックスが更新されるまで返ってきません。

To save multiple objects in JDO, call the makePersistentAll(...) method with a Collection of objects. In the current release, this is implemented similarly to a series of calls to makePersistent(). In a future release, this method will perform more efficient batch calls to the datastore.

JDOで複数のオブジェクトを保存するには、オブジェクトのコレクションを引数に、makePersistentAll(...)を呼んでください。現在のリリースでは、makePersistent()をそれぞれに呼ぶのと同様に実装されていますが、このメソッドは今後のリリースでより効率的にDatastoreのバッチ呼び出しとして実行されます。

Note: If any of the data object's persistent fields are references to other persistent data objects, and any of those objects have never been saved or have changed since they were loaded, the referenced objects will also be saved to the datastore. See Relationships.

注:対象のデータオブジェクトの永続化フィールドが、他の永続化データオブジェクトを参照しているときに、それらのオブジェクトが一度も保存されていない、または読み込まれたあと変更されている場合は、その参照されているオブジェクトもまたDatastoreに保存されます。Relationshipsを参照してください。

Keys

Every entity has a key that is unique over all entities in App Engine. A complete key includes several pieces of information, including the application ID, the kind, and an entity ID. (Keys also contain information about entity groups; see Transactions for more information.)

各エンティティはApp Engineの全てのエンティティで一意なキーをもっています。完全なキーは、そのアプリケーションのID、種類、エンティティIDなどを含む、いくつかの情報を持っています。(また、キーにはエンティティグループの情報を保持しています。詳細はTransactionsを参照してください。)

An object's key is stored in a field on the instance. You identify the primary key field using the @PrimaryKey annotation.

オブジェクトのキーは、そのインスタンスのフィールドに格納されます。@PrimaryKeyアノテーションを使用して、プライマリキーのフィールドを特定します。

The app can provide the ID portion of the key as a string when the object is created, or it can allow the datastore to generate a numeric ID automatically. The complete key must be unique across all entities in the datastore. In other words, an object must have an ID that is unique across all objects of the same kind and with the same entity group parent (if any). You select the desired behavior of the key using the type of the field and annotations.

アプリケーションは、オブジェクトが作られるときに、キーのIDの一部を文字列として渡すことができます。もしくは、Datastoreに自動的に数値のIDを生成させることもできます。完全なキーは Datastore内の全てのエンティティで一意である必要があります。言い換えると、オブジェクトは、同種の全てのオブジェクトで一意なIDと、(もし可能なら)同一のエンティティグループの親をもっていなければなりません。フィールドの型とアノテーションを利用して、望むようなキーの振る舞いを選択することができます。

If the class is used as a "child" class in a relationship, the key field must be of a type capable of representing an entity group parent: either a Key instance, or a Key value encoded as a string. See Transactions for more information on entity groups, and Relationships for more information on relationships.

そのクラスがリレーションシップ内で「子」クラスとして使われる場合、キーのフィールドはエンティティグループの親を表すことができるタイプでなければいけません。つまり、Keyのインスタンスか、Keyの値を文字列としてエンコードしたものです。エンティティグループの詳細はTransactions、リレーションシップの詳細はRelationshipsを参照してください。

Tip: If the app creates a new object and gives it the same string ID as another object of the same kind (and the same entity group parent), saving the new object overwrites the other object in the datastore. To detect whether a string ID is already in use prior to creating a new object, you can use a transaction to attempt to get an entity with a given ID, then create one if it doesn't exist. See Transactions.

Tip: もしアプリケーションが新しいオブジェクトを作成し、同種のほかのオブジェクト(そして同じエンティティグループの親)と同じ文字列のIDを渡した場合、その新しいオブジェクトはDatastore内のほかのオブジェクトを上書きします。新しいオブジェクトを作成すル前に、ある文字列のIDが既に使われていないか検出するには、トランザクションを利用して、そのIDでエンティティを検索し、存在しない場合にそのIDを使ってオブジェクトを作成してください。Transactionsを参照。

There are 4 types of primary key fields:

プライマリキーのフィールドには4つの種類があります。

Long

A long integer (java.lang.Long), an entity ID automatically generated by the datastore. Use this for objects without entity group parents whose IDs should be generated automatically by the datastore. The long key field of an instance is populated when the instance is saved.

Long Integer (java.lang.Long) エンティティIDはDatastoreによって自動的に生成されます。これは、Datastoreによって自動生成されるべきIDのエンティティグループの親をもたないオブジェクトに使用してください。インスタンスのLongキーのフィールドはそのインスタンスが保存されるときに設定されます。

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

// ...
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;
Unencoded String

A string (java.lang.String), an entity ID ("key name") provided by the application when the object is created. Use this for objects without entity group parents whose IDs should be provided by the application. The application sets this field to the desired ID prior to saving.

文字列 (java.lang.String)、オブジェクトが作成されるときに、アプリケーションによって提供されるエンティティID ("key name")。アプリケーションによって提供されるべきIDのエンティティグループの親をもたないオブジェクトに使用してください。アプリケーションは保存する前に、希望するIDをこのフィールドにセットします。

import javax.jdo.annotations.PrimaryKey;

// ...
    @PrimaryKey
    private String name;
Key

A Key instance (com.google.appengine.api.datastore.Key). The key value includes the key of the entity group parent (if any) and either the app-assigned string ID or the system-generated numeric ID. To create the object with an app-assigned string ID, you create the Key value with the ID and set the field to the value. To create the object with a system-assigned numeric ID, you leave the key field null. (For information on how to use entity group parents, see Transactions.)

Keyインスタンス(com.google.appengine.api.datastore.Key)。そのキーの値は、(もしあれば)エンティティグループの親のキーと、アプリケーションでアサインした文字列のIDかシステムで生成した数値のIDを含みます。アプリケーションがアサインした文字列のIDを使ってオブジェクトを作成するには、そのIDでKeyの値を生成し、その値をフィールドにセットしてください。システムがアサインした数値のIDでオブジェクトを生成する場合、キーフィールドをNullのままにしてください。(エンティティグループの親の使い方に関する情報は、Transactionsを参照してください。)

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;

// ...
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    public void setKey(Key key) {
        this.key = key;
    }

The app can create a Key instance using the KeyFactory class:

アプリケーションはKeyFactoryクラスを利用して、Keyのインスタンスを生成することができます。

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

// ...
        Key key = KeyFactory.createKey(Employee.class.getSimpleName(), "Alfred.Smith@example.com");
        Employee e = new Employee();
        e.setKey(key);
        pm.makePersistent(e);
Key as Encoded String

Similar to Key, but the value is the encoded string form of the key. Encoded string keys allow you to write your application in a portable manner and still take advantage of App Engine datastore entity groups.

Keyと似ていますが、その値はキーをエンコードした文字列の形です。Encoded Stringのキーは、移植性の高いアプリケーションを作成できるようにしますが、その利点はApp Engine datastoreでもあります。

import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;

// ...
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String encodedKey;

The app can populate this value prior to saving using a key with a name, or it can leave it null. If the encoded key field is null, the field is populated with a system-generated key when the object is saved.

アプリケーションは、キーと名前を利用して、保存する前にこの値を設定することもできますし、Nullのままにしておくこともできます。このフィールドがNullだった場合、このオブジェクトが保存されるときにシステムで生成されたキーが設定されます。

Key instances can be converted to and from the encoded string representation using the KeyFactory methods keyToString() and stringToKey().

KeyインスタンスはKeyFactoryのメソッド、 keyToString() とstringToKey()を使って、エンコードされた文字列表現にしたり、復元したりすることができます。

When using encoded key strings, you can provide access to an object's string or numeric ID with an additional field:

エンコードされたキーの文字列を利用する場合、追加のフィールドでオブジェクトの文字列または数値のIDにアクセスできるようにする必要があります。

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
    private String encodedKey;

    @Extension(vendorName="datanucleus", key="gae.pk-name", value="true")
    private String keyName;

    // OR:

    @Extension(vendorName="datanucleus", key="gae.pk-id", value="true")
    private Long keyId;

A "gae.pk-name" field can be set to a key name prior to saving the object. When the object is saved, the encoded key field is populated with the complete key that includes the key name. Its type must be String.

"gae.pk-name"フィールドはオブジェクトを保存する前にキー名を設定することができます。オブジェクトが保存されると、エンコードされたキーのフィールドは、キー名を含む完全なキーが設定されます。その型はStringでなければなりません。

A "gae.pk-id" field is populated when the object is saved, and cannot be modified. Its type must be Long.

"gae.pk-id"フィールドは、オブジェクトが保存されたときに設定されます。そして変更することはできません。これはLong型でなければなりません。

When a new object with a generated key (a key field using valueStrategy = IdGeneratorStrategy.IDENTITY) is created, its key value starts out null. The key field is populated when the object is written to the datastore. If you are using a transaction, the object is written when the transaction is committed. Otherwise, the object is written when the makePersistent() method is called if the object is being created, or when the PersistenceManager instance's close() method is called if the object is being updated.

生成されたキー(キーのフィールドにはvalueStrategy = IdGeneratorStrategy.IDENTITYを使用)とともに新しいオブジェクトが生成されたとき、そのキーの値は最初はNullです。このキーのフィールドはオブジェクトがDatastoreに書き込まれたときに設定されます。もし、トランザクションを利用している場合は、そのオブジェクトはトランザクションがコミットされたときに書き込まれます。その他の場合、そのオブジェクトが生成されたときは makePersistent()が呼ばれた場合、またオブジェクトが更新されるときはPersistenceManagerのインスタンスの close()メソッドが呼ばれた場合に設定されます。

Creating and Using Keys

If the application knows every element of an entity's complete key, the application can create the corresponding Key object without the object.

アプリケーションがエンティティの完全なキーの各要素を知っている場合、アプリケーションは対応するKeyオブジェクトを、そのオブジェクトなしで生成することができます。

For a key for an entity without an entity group parent, you can use the createKey() static method of the KeyFactory class. This method takes a kind (the simple name of the class) and either an app-assigned string ID or a system-assigned numeric ID, and returns a Key object. For example, to recreate the key of an entity of kind "Employee" with key name "Alfred.Smith@example.com" (and no entity group parent):

エンティティグループの親のない場合のキーは、 KeyFactoryクラスのスタティックメソッドである、 createKey()を使えます。このメソッドは種類(クラスのシンプルネーム)とアプリケーションの設定した文字列IDまたはシステムの設定した数値IDを引数にとり、Keyオブジェクトを返します。たとえば、エンティティーの種類"Employee"とキー名"Alfred.Smith@example.com"(そしてエンティティグループの親がない)でキーを再生成します。

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

// ...
        Key k = KeyFactory.createKey(Employee.class.getSimpleName(), "Alfred.Smith@example.com");

To recreate a key of an entity of kind "Employee" with a system-assigned numeric ID of 52234 (and no entity group parent):

エンティティの種類が"Employee"で、システムが設定した数値IDが52234(かつエンティティグループの親がない)のキーを再生成するには

        Key k = KeyFactory.createKey(Employee.class.getSimpleName(), 52234);

Keys can be converted to and from a string representation using the KeyFactory class's keyToString() and stringToKey() methods, respectively. (Note that this is different from the Key class's toString() method, which returns a human-readable value suitable for debugging.)

キーはKeyFactoryクラスのkeyToString() とstringToKey()で文字列と相互に変換できます。(KeyクラスのtoString()とは異なることに注意してください。こちらはデバッグに適した人間が読むための文字列を返します。)

For a key for an entity with an entity group parent, you can use the KeyFactory.Builder class:

エンティティとエンティティグループの親のためのキーには、KeyFactory.Builderクラスを使用してください。

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

// ...
        Key k = new KeyFactory.Builder(Employee.class.getSimpleName(), 52234).addChild(ExpenseReport.class.getSimpleName(), "A23Z79").getKey();

The Builder instance's addChild() method returns the Builder, so you can chain calls to add each element of the key path. To get the complete Key value for a given builder, you call the Builder's getKey() method.

BuilderインスタンスのaddChild()メソッドはBuilderを返します。よって、キーのパスの要素を追加するためにチェインコールができます。完全なKeyの値を得るために、BuilderのgetKey()メソッドを呼んでください。

For more information about entity groups, see Transactions.

エンティティグループの詳細については、Transactionsを参照して下さい。

Getting an Object By Key

To retrieve an object given its key, use the PersistenceManager's getObjectById() method. The method takes the class for the object, and key:

キーからオブジェクトを取得するには、PersistenceManagerの getObjectById()メソッドを使います。このメソッドは、オブジェクトのクラスと、キーを引数にとります。

        Key k = KeyFactory.createKey(Employee.class.getSimpleName(), "Alfred.Smith@example.com");
        Employee e = pm.getObjectById(Employee.class, k);

If the class uses a key field that is an unencoded string ID (String) or numeric ID (Long), getObjectByID() can take the simple value as the key parameter:

もしクラスがエンコードされていない文字列のID(String)または数値ID(Long)のキーフィールドを使っている場合、getObjectByID()はキーパラメータとして単純な値をとります。

        Employee e = pm.getObjectById(Employee.class, "Alfred.Smith@example.com");

The key argument can be of any of the supported key field types (string ID, numeric ID, Key value, encoded key string), and can be of a different type than the key field in the class. App Engine must be able to derive the complete key from the class name and the provided value. String IDs and numeric IDs are exclusive, so a call using a numeric ID will never return an entity with a string ID. If a Key value or encoded key string is used, the key must refer to an entity whose kind is represented by the class.

キーの引数は、サポートされているいかなるキーフィールドの型(文字列ID、数値ID、Key、エンコード化されたキー文字列)でもとることができます。そして、クラスのキーフィールドと異なる型も使えます。AppEngineはクラス名と与えられた値から完全なキーを導出できなければなりません。文字列IDと数値IDは排他的です。よって数値IDをつかって呼び出すと、文字列 IDのエンティティは決して戻りません。Key値またはエンコードされたキー文字列が使われている場合、そのキーは、クラスによって表される種類のエンティティを参照しなければなりません。

Updating an Object

One way to update an object with JDO is to fetch the object, then modify it while the PersistenceManager that returned the object is still open. Changes are persisted when the PersistenceManager is closed. For example:

JDOをつかってオブジェクトを更新する一つの方法は、PersistenceManagerがオブジェクトを戻して開いている間に変更することです。変更はPersistenceManagerが閉じられたときに保存されます。例えば

public void updateEmployeeTitle(User user, String newTitle) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
        Employee e = pm.getObjectById(Employee.class, user.getEmail());
        if (titleChangeIsAuthorized(e, newTitle) {
            e.setTitle(newTitle);
        } else {
            throw new UnauthorizedTitleChangeException(e, newTitle);
        }
    } finally {
        pm.close();
    }
}

Since the Employee instance was returned by the PersistenceManager, the PersistenceManager knows about any modifications that are made to Persistent fields on the Employee and automatically updates the datastore with these modifications when the PersistenceManager is closed. It know this because the Employee instance is "attached" to the PersistenceManager.

EmployeeインスタンスがPersistenceManagerから戻されたとき、PersistenceManagerはEmployeeの永続化フィールドにされた変更をしっており、PersistenceManagerが閉じられたときにそれらの変更は自動的にDatastoreに反映されます。Employeeインスタンスは、PersistenceManagerに「アタッチ」されているからです。

You can modify an object after the PersistenceManager has been closed by declaring the class as "detachable." To do this, add the detachable attribute to the @PersistenceCapable annotation:

対象のクラスを"detachable"として宣言することにより、PersistenceManagerが閉じられてからオブジェクトを変更することができます。これを行うには@PersistenceCapableアノテーションにdetachable属性を付加します。

import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class Employee {
    // ...
}

Now you can read and write the fields of an Employee object after the PersistenceManager that loaded it has been closed. The following example illustrates how a detached object might be useful:

これで、 PersistenceManagerによってロードされたEmployeeオブジェクトのフィールドを、PersistenceManagerが閉じられたあとも、読み書きすることができます。次の例でデタッチされたオブジェクトがどのように役に立つかを表しています。

public Employee getEmployee(User user) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    pm.setDetachAllOnCommit(true);
    try {
        e = pm.getObjectById(Employee.class, "Alfred.Smith@example.com");
    } finally {
        pm.close();
    }
    return e;
}

public void updateEmployeeTitle(Employee e, String newTitle) {
    if (titleChangeIsAuthorized(e, newTitle) {
        e.setTitle(newTitle);
        PersistenceManager pm = PMF.get().getPersistenceManager();
        try {
            pm.makePersistent(e);
        } finally {
            pm.close();
        }
    } else {
        throw new UnauthorizedTitleChangeException(e, newTitle);
    }
}

Detached objects are a nice alternative to creating data transfer objects. For more information on working with detached objects please see the DataNucleus documentation.

デタッチされたオブジェクトはDTOを作成する良い代替です。デタッチされたオブジェクトをどのように使うかについての情報はDataNucleus documentationを参照してください。

Deleting an Object

To delete an object from the datastore, call the PersistenceManager's deletePersistent() method with the object:

Datastoreからオブジェクトを削除するには、PersistenceManagerのdeletePersistent()メソッドに対象のオブジェクトを渡してよんでください

        pm.deletePersistent(e);

If an object has fields containing child objects that are also persistent, the child objects are also deleted. See Relationships for more information.

もし、オブジェクトが子オブジェクトをもっている場合、その子オブジェクトもまた削除されます。詳細はRelationshipsを参照してください。

0 件のコメント: