Hello again and welcome to this week's installment of JDO/JPA Snippets That Work: Executing Batch Gets
Did you know that the App Engine datastore supports batch gets? Batch gets are a super-efficient way to load multiple entities when you already have the keys of the entities you want loaded. Here's an example using the low-level Datastore API:
public Map<Key, Entity> getById(List<Key> keys) {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
return ds.get(keys);
}
Now lets see how we can accomplish the same thing in JPA and JDO:
JPA:
@Entity
public class Book {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;
private String title;
// additional members, getters and setters
}
public List<Book> getById(List<Key> keys) {
Query q = em.createQuery("select from " + Book.class.getName() + " where key = :keys");
q.setParameter("keys", keys);
return (List<Book>) q.getResultList();
}
JDO:
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Book {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Key key;
private String title;
// additional members, getters and setters
}
public List<Book> getById(List<Key> keys) {
Query q = pm.newQuery("select from " + Book.class.getName() + " where key == :keys");
return (List<Book>) q.execute(keys);
}
Notice how in both examples we're constructing a query to pull back the entities by key. The App Engine JDO/JPA implementation detects queries that are filtering only by key and fulfills them using a low level batch get rather than a datstore query. This works no matter the type of your primary key field, so whether you're using a Long, an unencoded String, an encoded String, or a Key, the same technique will work. However, even though this looks like a query, all the fetch-related transaction restrictions apply: if you're executing your batch get query inside a txn, all of the entities you're attempting to fetch must belong to the same entity group or you'll get an exception. Be careful with this.
The next time you need to pull back multiple entities and you already have their keys, issue a query that filters only by your object's key field and reap the benefits of the datastore's optimized batch get mechanism.
Until next time....
Max
转载:
http://groups.google.com/group/google-appengine-java/browse_thread/thread/d907ba54c579e9ed?hl=en#