子对象和关系
作为 @PersistenceCapable
类的实例的字段值在两个对象之间创建自有的一对一关系。作为此类引用的集合的字段创建自有的一对多关系。
重要信息:自有的关系具有事务、实体组和级联删除的隐含意义。有关详细信息,请参阅事务和关系。
嵌入类
通过嵌入类,您可以使用类来建模字段值,无需创建新的数据存储区实体并形成关系。该对象值的字段直接存储在含有对象的数据存储区实体中。
任何 @PersistenceCapable
数据类都可用作另一个数据类中的嵌入对象。类的 @Persistent
字段嵌入到对象中。如果让类嵌入@EmbeddedOnly
批注,则该类只能用作嵌入类。嵌入类不需要主键字段,因为它不作为单独的实体存储。
嵌入类的字段作为实体上的属性存储,使用每个字段的名称以及对应属性的名称。如果类型为嵌入类的对象上有多个字段,则必须重命名这些字段以使它们不会互相冲突。您可以使用 @Embedded
批注的参数来指定新的字段名称。
类似地,对象上的字段不可以使用与嵌入类的字段冲突的名称,除非重命名嵌入的字段。
因为嵌入类的持久属性存储在与其他字段相同的实体上,所以您可以在 JDOQL 查询过滤条件和排序顺序中使用嵌入类的持久字段。您可以使用外部字段的名称、点 (.
) 以及嵌入字段的名称来引用嵌入字段。不管是否使用 @Column
批注更改了嵌入字段的属性名称,这都同样适用。
集合
一个数据存储区属性可以具有多个值。在 JDO 中,这是通过集合类型的单一字段来表示的,其中集合为核心值类型之一或 Serializable 类。支持以下集合类型:
java.util.ArrayList<...>
java.util.HashSet<...>
java.util.LinkedHashSet<...>
java.util.LinkedList<...>
java.util.List<...>
java.util.Set<...>
java.util.SortedSet<...>
java.util.Stack<...>
java.util.TreeSet<...>
java.util.Vector<...>
如果某个字段声明为 List,则数据存储区返回的对象将具有 ArrayList 值。如果某个字段声明为 Set,则数据存储区返回 HashSet。如果某个字段声明为 SortedSet,则数据存储区返回 TreeSet。
对象字段和实体属性
App Engine 数据存储区区分不具有指定属性的实体和该属性值为 null
的实体。JDO 不支持这种区分:对象的每个字段都有一个值,可能是 null
。如果将某个具有可设为 null 的值类型(不同于 int
或 boolean
之类的内置类型)的字段设置为 null
,则在保存对象时,所得实体会将该属性设置为 null 值。
如果将一个数据存储区实体载入对象中,对于该对象中的某一个字段,实体中没有对应的属性,且该字段是可设为 null 的单值类型,则该字段将设置为 null
。在将该对象保存回数据存储区时,null
属性将在数据存储区中被设置为 null 值。如果该字段不是可设为 null 的值类型,则载入没有对应属性的实体将引发异常。如果实体是从用于重新创建实例的相同的 JDO 类创建的,则这种情况不会发生,但是如果 JDO 类发生变化,或者实体是使用低级别 API 而非 JDO 创建的,则会出现这种情况。
如果某个字段的类型是核心数据类型的集合或 Serializable 类,而实体上的属性没有值,则会在数据存储区中将该属性设置为单一 null 值来表示该空集合。如果该字段的类型是数组类型,则会为其分配 0 个元素的数组。如果已载入对象而属性没有值,则将为该字段分配相应类型的空集合。在内部,数据存储区已知空集合与包含一个 null 值的集合之间的区别。
如果实体具有一个在对象中没有对应字段的属性,则无法从该对象访问该属性。如果将对象保存回数据存储区,将删除这个额外的属性。
如果某个实体具有一个值类型与对象中对应字段的类型不同的属性,则 JDO 会尝试将该值转换成字段类型。如果无法将该值转换成字段类型,则 JDO 将引发 ClassCastException。在值为数字(长整型或双精度浮点型)的情况下,将对该值进行转换 (convert),而不是对类型进行转换 (cast)。如果数字属性值超出字段类型的表示范围,则转换将溢出,而不会引发异常。
创建、获取和删除数据
将 JDO 数据对象保存到数据存储区只需调用 PersistenceManager 实例的 makePersistent()
方法。App Engine JDO 实现使用对象的主键字段来跟踪哪个数据存储区实体与该数据对象对应,并可以为新对象自动生成键。您可以使用键快速地检索实体,并从已知值(例如帐户 ID)构造键。
使对象持久
要将简单数据对象存储到数据存储区中,您可以调用 PersistenceManager 的 makePersistent()
方法,将实例传递给该方法。
PersistenceManager pm = PMF.get().getPersistenceManager();
Employee e = new Employee("Alfred", "Smith", new Date());
try {
pm.makePersistent(e);
} finally {
pm.close();
}
对 makePersistent()
的调用是同步的,直到保存对象并更新索引后才会返回。
要在 JDO 中保存多个对象,请对一组对象调用 makePersistentAll(...)
方法。在目前的版本中,该方法的实现类似对makePersistent()
的一系列调用。在未来的版本中,该方法将对数据存储区执行更高效的批量调用。
注意:如果有任何数据对象的持久字段是对其他持久数据对象的引用,且任何这些对象自加载后从未保存过或已发生更改,则引用的对象也将保存到数据存储区。请参阅关系。
键
每个实体都具有一个在 App Engine 的所有实体中唯一的键。一个完整的键包含若干条信息,其中包括应用程序 ID、类型和实体 ID。(键也包含有关实体组的信息,有关详细信息,请参阅事务。)
对象的键存储在实例的某一个字段中。您可以使用 @PrimaryKey
批注来标识主键字段。
应用程序可在创建对象时以字符串形式提供键的 ID 部分,也可以允许数据存储区自动生成数字 ID。完整的键在数据存储区的所有实体中必须是唯一的。换句话说,在类型相同且具有相同父实体组(如果有)的所有对象中,一个对象必须具有唯一的 ID。您可以使用字段类型和批注来选择所需的键的行为。
如果类用作关系中的“子”类,则键字段必须为能够代表父实体组的类型:Key 实例或编码为字符串的键值。有关实体组的详细信息,请参阅事务;有关关系的详细信息,请参阅关系。
提示:如果应用程序创建一个新对象,并为其指定了与类型相同(且具有相同父实体组)的另一对象相同的字符串 ID,则保存该新对象时将覆盖数据存储区中的另一对象。要在创建新对象前检测字符串 ID 是否已经被使用,您可以使用事务尝试获取具有指定 ID 的实体,如果该实体不存在,则您可以继续创建。请参阅事务。
主键字段有 4 种类型:
长整型
长整型 (java.lang.Long
):由数据存储区自动生成的实体 ID。对于没有父实体组、其 ID 应由数据存储区自动生成的对象,请使用此类型。实例的长整型键字段在该实例保存时填充。
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
// ...
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
未编码字符串
一个字符串 (java.lang.String
):对象创建时由应用程序提供的实体 ID(“键名”)。对于没有父实体组、其 ID 应由应用程序提供的对象,请使用此类型。应用程序在保存前将此域设置为所需的 ID。
import javax.jdo.annotations.PrimaryKey;
// ...
@PrimaryKey
private String name;
键
Key 实例 (com.google.appengine.api.datastore.Key
)。键值包括父实体组(如果有)的键以及应用程序分配的字符串 ID 或系统生成的数字 ID。要创建带应用程序分配的字符串 ID 的对象,请创建带有该 ID 的键值并将字段设置为该值。要创建带系统分配的数字 ID 的对象,请将键字段留为 null。有关如何使用父实体组的信息,请参阅事务。
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;
}
应用程序可以使用 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);
编码字符串形式的键
与键类似,但值是键的编码字符串形式。编码字符串键允许您以便携方式编写应用程序且仍可以利用 App Engine 数据存储区实体组。
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;
应用程序可以在保存前使用带名称的键填充该值,或将它留为 null。如果编码的键字段为 null,则将在保存对象时使用系统生成的键填充该字段。
Key 实例和编码字符串表示可以通过 KeyFactory 方法 keyToString()
和 stringToKey()
进行相互转换。
当使用编码键字符串时,您可以通过一个额外的字段提供对对象的字符串 ID 或数字 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;
"gae.pk-name"
字段可以在保存对象前设置为键名称。保存对象时,将使用包括键名称的完整键填充编码键字段。其类型必须为 String。
"gae.pk-id"
字段在对象保存时填充,且无法修改。其类型必须为 Long。
创建带生成的键(使用 valueStrategy = IdGeneratorStrategy.IDENTITY
的键字段)的新对象时,其键值初始为 null
。键字段在对象写入数据存储区时填充。如果使用事务,则对象在事务提交时写入。否则,如果创建对象,则对象在调用 makePersistent()
方法时写入;如果更新对象,则对象在调用 PersistenceManager 实例的 close()
方法时写入。
创建和使用键
如果应用程序已知实体的完整键的所有元素,则应用程序可以在没有对象的情况下创建对应的 Key
对象。
对于没有父实体组的实体的键,您可以使用 KeyFactory
类的 createKey()
静态方法。该方法采用类型(类的简单名称)和应用程序分配的字符串 ID 或系统分配的数字 ID,并返回 Key
对象。例如,要重新创建键名称为 "Alfred.Smith@example.com"
的 "Employee"
类型的实体的键(无父实体组):
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");
要重新创建系统分配的数字 ID 为 52234
的 "Employee"
类型的实体的键(无父实体组):
Key k = KeyFactory.createKey(Employee.class.getSimpleName(), 52234);
可以使用 KeyFactory 类的 keyToString()
方法将键转换为字符串表示,使用 stringToKey()
方法将字符串表示转换为键。(请注意,这与 Key 类的 toString()
方法不同,该方法返回适用于调试的用户可读的值。)
对于具有父实体组的实体的键,您可以使用 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();
Builder 实例的 addChild()
方法返回 Builder,因此您可以连锁调用以添加键路径的每一个元素。要获取指定 Builder 的完整键值,您可以调用该 Builder 的 getKey()
方法。
有关实体组的详细信息,请参阅事务。
相关推荐
数据生成是通过 CPIM 和 Kundera GAE 数据存储扩展提供的。 ###Bulild 只需运行: mvn clean package 创建了一个可执行的 jar。 请注意,pom 文件包含的修改版本和作为依赖项,这些在 maven 的公共存储库中不...
GAE是Google提供的一个云计算平台,允许开发者在Google的基础设施上部署和运行Web应用,提供了包括计算、存储、数据库等在内的多种服务。 首先,Google App Engine(GAE)是Google推出的一个PaaS(Platform as a ...
2. **数据存储**:Spring与GAE的数据存储API(如JDO或JPA)结合,可以提供一个统一的数据访问层,简化对Google Datastore的操作。 3. **调度任务**:Spring的TaskExecution和TaskScheduler模块可以与GAE的后台任务...
【标题】"gae-pytorch-master_pytorch_pytorchgae_GAE_自编码器_gaepytorchmaster_" 提供的信息表明,这是一个使用PyTorch实现的图自编码器(Graph Autoencoder, GAE)项目,其核心是将自编码器的概念应用于图数据。...
- `Photo` Bean:定义了存储图像所需的信息,如标题、说明和二进制数据。 - Datastore DAO:使用Objectify库来与Bigtable交互,实现存储和检索`Photo`对象。 - Servlet:采用Template Method模式封装工作流程,对每...
《GAE编程指南》是一种云计算服务,跟其他的同类产品不同,它提供了一种简单的应用程序...你将会学到有关App Engine的应用程序服务器架构、运行时环境以及可伸缩数据存储区等知识,还可以学到一些应用程序优化方法。
GAE使用规则GAE使用规则GAE使用规则GAE使用规则GAE使用规则GAE使用规则GAE使用规则GAE使用规则GAE使用规则
**App Engine Java SDK** 是开发GAE Java应用的核心工具,它包含了运行和测试应用所需的服务器软件,以及模拟所有GAE服务的本地版本,如**数据存储区**、**Google账户集成**和API调用。SDK还允许你在本地计算机上...
DSQL扩展了gae数据存储区,以实现各种数据存储区之间的本地联接,以及为未索引的属性提供本地过滤。 DSQL使用熟悉的sql语法。 SQL联接使用数据存储统计信息进行了优化。 假定数据存储架构的设计类似于关系数据库。...
图形自动编码器(Graph Autoencoder, GAE)是一种应用于图数据的深度学习模型,它结合了自动编码器(Autoencoder)的思想与图神经网络(Graph Neural Network, GNN)的特性。GAE的目标是学习到图的低维表示,即节点...
【gae strus2 spring 整合】是一种在Google App Engine(GAE)平台上将Struts2和Spring框架集成的技术方案。这种整合旨在充分利用Struts2的MVC架构和Spring的依赖注入(DI)以及面向切面编程(AOP)能力,以构建高效...
《GAE编程指南》是一种云计算服务,跟其他的同类产品不同,它提供了一种简单的应用程序...你将会学到有关App Engine的应用程序服务器架构、运行时环境以及可伸缩数据存储区等知识,还可以学到一些应用程序优化方法。
pass之GAE入门教程, 学习GAE
标题中的“GAE Struts2配置”指的是在Google App Engine (GAE) 上配置Struts2框架的过程。GAE是一个基于Java的云平台,允许开发者部署Web应用,而Struts2是一个流行的MVC(模型-视图-控制器)框架,用于构建Java Web...
- GAE 使用自己的数据存储系统,称为 Datastore,提供了 NoSQL 数据模型。 - 查询语言 GQL 类似于 SQL,用于检索和操作数据。 8. **使用模板文件** - Django 模板引擎可以用于创建动态网页,实现数据和页面结构...
### GAE之webapp框架详解 #### 一、引言 在Google App Engine (GAE) 平台上进行Web应用开发时,选择合适的框架对于提高开发效率至关重要。其中,`webapp` 框架因其简洁高效而备受开发者青睐。本篇文章将详细介绍`...
2. **项目结构**:在GAE上部署应用通常需要一个特定的项目结构,包括`app.yaml`配置文件,它定义了应用的运行环境、服务、版本和其他元数据。在给定的文件名称列表中,我们看到了`index.yaml`,这通常是用于定义应用...
2. Python解释器:GAE通常使用的Python版本,可能已经配置好与GAE兼容的环境。 3. 一个名为SDU的文件夹,其中包含一个exe文件,这可能是自定义的管理工具或者GAE的启动程序。 4. localproxy文件夹:内含proxy.py,如...
3. **数据存储**:GAE提供了NoSQL数据库服务,称为**Datastore**。它是一种非关系型分布式数据库,支持高可用性和可扩展性。了解其数据模型(实体、键、属性)和查询语言(GQL或通过API)是至关重要的。 4. **服务...