繁体   English   中英

具有Olingo V4和MySQL数据库连接的OData服务

[英]OData Service with Olingo V4 and MySQL database connection

我正在关注一些示例,在该示例中,我们可以使用Java的Olingo (Maven项目)构建OData服务 提供的示例没有任何数据库交互。 他们正在使用一些Storage.class ,其中包含硬编码数据。

您可以在git上找到示例代码。 请在提供的网址中参考示例p0_all

有谁知道我们如何将git示例与某些数据库连接并进一步执行CRUD操作

请通过一些好的例子或概念帮助我。

预先感谢您。

我最近使用Olingo建立了一个oData生产者,发现自己同样感到沮丧。 我认为问题的一部分在于,实际上有很多不同的方法可以使用Olingo构建oData服务,而数据访问部分完全取决于开发人员是否可以在他们自己的项目中进行选择。

首先,您需要一个已建立数据库连接的应用程序。 因此,完全不考虑Olingo,您应该拥有一个可以连接并可以查询数据库的应用程序。 如果不确定如何构建可查询MySQL数据源的Java应用程序,那么您应该在Google周围寻找与该问题相关的教程,并且与Olingo无关。

接下来,您需要编写方法和查询以在应用程序中执行CRUD操作。 同样,这些方法与Olingo无关。

Olingo开始发挥作用的是您对处理器类的实现。 EntityCollectionProcessorEntityProcessor等(请注意,还有其他一些问题,例如设置CsdlEntityTypes和Schema / Service Document等,但是这些问题不在您的问题范围内)

让我们从EntityCollectionProcessor开始。 通过实现EntityCollectionProcessor类,您需要重写readEntityCollection()函数。 此功能的目的是解析ODATA URI用于实体名称,取一个EntityCollectionEntity ,然后序列化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数据库并返回给定实体的所有记录(使用实体的字符串名称)。 然后,一旦有了记录的列表或集合(或其他集合),就需要将其转换为EntityCollection

顺便说一句,我认为这可能是Olingo示例与实际应用程序之间脱节的来源。 getData(edmEntitySet);后面的代码getData(edmEntitySet); 可以根据基础系统中使用的设计模式(MVC等),样式选择,可伸缩性要求等,以无限不同的方式来构造呼叫。

这是一个示例,说明了如何从查询返回的List中创建EntityCollection (请记住,我假设您知道如何查询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>转换为EntityCollection EntityCollection是通过调用createEntity()函数进行的,该函数接受我的Foo对象的实例并将其转换为Olingo Entity 然后,将EntityCollection返回到readEntityCollection()函数,可以将其正确序列化并作为oData响应返回。

该示例通过自己的示例暴露了Olingo所遇到的一些体系结构问题。 在我的示例中,Foo是一个对象,该对象具有用于标识字段名称的常量,Olingo使用这些常量来生成oData Schema和Service Document。 这个对象有一个方法来返回它自己的CsdlEntityType ,以及一个构造函数,它自己的属性以及getters / setters等。您不必以这种方式来设置系统,但是对于我的项目的可伸缩性要求,这就是我选择做事。

这是Olingo使用的一般模式。 覆盖接口的方法,然后在系统的单独部分中调用以所需方式与数据交互的函数。 然后将数据转换为Olingo可读对象,以便它们可以执行响应中需要完成的“ oData内容”。 如果要为单个实体实现CRUD,则需要实现EntityProcessor及其各种CRUD方法,并且在这些方法内部,需要调用系统中的函数(与任何Olingo代码完全分开),这些函数create()read() (单个实体), update()delete()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM