你好,欢迎来到这个星期的"JDO/JPA Snippets That Work"环节:执行批量的Gets
你知道App Engine datastore支持批量的gets吗?当你已经获得entities的keys,而你又想获得这些keys对应的entities的时候,批量的gets是一个超级高效解决方法。
这里是使用low-leval的Datastore的API的例子:
public Map<Key, Entity> getById(List<Key> keys) {
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
return ds.get(keys);
}
现在让我们看下如何使用jpa和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);
}
注意在两个例子中,我们是如何构造一个query,利用key去pull回那些entities的。App Engine JDO/JPA实现了一个以key作过滤条件的,代替底层datastore查询的detects查询。这个做法是对任何类型的主键都有效的,所以无论你用Long,还是一个unencoded的String,或是一个encoded的String,或是一个Key类型,都是有效的。然而,即使这个看上去像一个query,但所有的fetch-related都受到这样的限制:如果你执行的批量get查询在一个transaction里面,所有你想获得的entities必须属于相同的entity group,否则你会得到一个exception.请注意这一点。
下次当你需要pull回多个entities而你又已经有了他们的keys的时候,就可以使用这个datastore的最佳的机制去批量get这些entities了。
英语原文:
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#
说明:上面的中文翻译是我用自己能理解的方式翻译出来的,并不是逐字翻译,只作为自己参考用,并不十分精确。