我正在关注一些example,我们可以在其中使用来自Java的Olingo (maven项目)构建 OData服务。提供的示例没有任何数据库交互。他们正在使用一些 Storage.class ,其中包含硬编码数据。
您可以在git上找到示例代码。请参阅提供的网址中的示例p0_all
。
有谁知道我们如何将git示例连接到某个数据库并进一步执行CRUD操作
请帮我一些好的例子或概念。
提前感谢你。
答案 0 :(得分:3)
我最近使用Olingo构建了一个oData制作人,并发现自己同样感到沮丧。我认为问题的一部分是,使用Olingo构建oData服务确实有很多不同的方法,数据访问部分完全取决于开发人员在他们自己的项目中进行整理。
首先,您需要一个设置了数据库连接的应用程序。完全无视Olingo,你应该有一个连接到并可以查询数据库的应用程序。如果您不确定如何构建可以查询MySQL数据源的Java应用程序,那么您应该在Google周围寻找与该问题相关的教程,并与Olingo无关。
接下来,您需要编写方法和查询以在应用程序中执行CRUD操作。同样,这些方法与Olingo无关。
Olingo开始进入游戏的地方是你的处理器类的实现。 EntityCollectionProcessor
,EntityProcessor
等(请注意,还有其他问题,例如设置CsdlEntityTypes和架构/服务文档等,但这些问题超出了您的问题范围)
让我们先看一下EntityCollectionProcessor
。通过实现EntityCollectionProcessor
类,您需要覆盖readEntityCollection()
函数。此函数的目的是解析实体名称的oData URI,为EntityCollection
获取Entity
,然后将EntityCollection
序列化为符合oData的响应。以下是您的示例链接中readEntityCollection()
的实现:
public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat)
throws ODataApplicationException, SerializerException {
// 1st we have retrieve the requested EntitySet from the uriInfo object
// (representation of the parsed service URI)
List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0);
// in our example, the first segment is the EntitySet
EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet();
// 2nd: fetch the data from backend for this requested EntitySetName
// it has to be delivered as EntityCollection object
EntityCollection entitySet = getData(edmEntitySet);
// 3rd: create a serializer based on the requested format (json)
ODataSerializer serializer = odata.createSerializer(responseFormat);
// 4th: Now serialize the content: transform from the EntitySet object to InputStream
EdmEntityType edmEntityType = edmEntitySet.getEntityType();
ContextURL contextUrl = ContextURL.with().entitySet(edmEntitySet).build();
final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName();
EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().id(id).contextURL(contextUrl).build();
SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts);
InputStream serializedContent = serializerResult.getContent();
// Finally: configure the response object: set the body, headers and status code
response.setContent(serializedContent);
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());
}
除了“第二步”之外,您可以忽略(并重复使用)此示例中的所有内容:
EntityCollection entitySet = getData(edmEntitySet);
这行代码是Olingo最终开始与我们的底层系统交互的地方,我们在这里看到的模式告诉我们应该如何设置其余的CRUD操作。
在您想要的任何课程中,函数getData(edmEntitySet)
可以是您想要的任何内容。唯一的限制是必须返回EntityCollection
。因此,您需要做的是调用查询MySQL数据库的函数,并返回给定实体的所有记录(使用实体的字符串名称)。然后,一旦您拥有List或Set(或其他)记录,您需要将其转换为EntityCollection
。
顺便说一下,我认为这可能是Olingo示例和现实世界应用程序之间脱节的地方。 getData(edmEntitySet);
调用背后的代码可以以无限不同的方式构建,具体取决于底层系统中使用的设计模式(MVC等),样式选择,可伸缩性要求等。
以下是我如何从查询返回的EntityCollection
创建List
的示例(请记住,我假设您知道如何查询MySQL数据源并已编写函数检索给定实体的所有记录):
private List<Foo> getAllFoos(){
// ... code that queries dataset and retrieves all Foo records
}
// loop over List<Foo> converting each instance of Foo into and Olingo Entity
private EntityCollection makeEntityCollection(List<Foo> fooList){
EntityCollection entitySet = new EntityCollection();
for (Foo foo: fooList){
entitySet.getEntities().add(createEntity(foo));
}
return entitySet;
}
// Convert instance of Foo object into an Olingo Entity
private Entity createEntity(Foo foo){
Entity tmpEntity = new Entity()
.addProperty(createPrimitive(Foo.FIELD_ID, foo.getId()))
.addProperty(createPrimitive(Foo.FIELD_FOO_NAME, foo.getFooName()));
return tmpEntity;
}
为了更加清晰,getData(edmEntitySet)
可能如下所示:
public EntityCollection getData(String edmEntitySet){
// ... code to determine which query to call based on entity name
List<Foo> foos = getAllFoos();
EntityCollection entitySet = makeEntityCollection(foos);
return entitySet;
}
如果您可以找到使用DataProvider类的Olingo示例,则可以使用一些基本示例来说明如何设置// ...code to determine which query to call based on entity name
。我最终使用Java反射大量修改了这种模式,但这与你的问题完全无关。
所以getData(edmEntitySet)
是一个函数,它接受一个实体名称,在数据源中查询该实体的所有记录(返回List<Foo>
),然后将List<Foo>
转换为{{ 1}}。 EntityCollection
是通过调用EntityCollection
函数来生成的,该函数接受我的createEntity()
对象的实例并将其转换为Olingo Foo
。然后Entity
返回到EntityCollection
函数,可以正确序列化并作为oData响应返回。
这个例子揭示了Olingo的一些架构问题以及它自己的例子。在我的示例中,Foo是一个对象,其中包含用于标识字段名称的常量,Olingo使用这些常量来生成oData架构和服务文档。这个对象有一个返回它自己的readEntityCollection()
的方法,以及一个构造函数,它自己的属性和getter / setter等。你不必以这种方式设置你的系统,但是对于我的可伸缩性要求这就是我选择做事的方式。
这是Olingo使用的一般模式。覆盖接口的方法,然后在系统的单独部分中调用函数,以期望的方式与数据交互。然后将数据转换为Olingo可读对象,以便他们可以执行响应中需要执行的任何“oData stuff”。如果要为单个实体实现CRUD,则需要实现EntityProcessor及其各种CRUD方法,并且在这些方法中,您需要调用系统中的函数(完全独立于任何Olingo代码){{1} },CsdlEntityType
(单一实体),create()
或read()
。