欢迎回到我们的教程系列“带有Hibernate OGM的NoSQL”! 感谢Gunnar Morling( @gunnarmorling )创建了本教程。 在这一部分中,您将学习如何在WildFly服务器上运行的Java EE应用程序中使用Hibernate OGM。 使用本教程前面部分已经知道的实体模型 ,我们将构建一个基于REST的小型应用程序来管理加息。 如果您还没有阅读本系列的前两期,则可以在这里找到它们:

  • 带有Hibernate OGM的NoSQL –第一部分:持久化您的第一个实体
  • 带有Hibernate OGM的NoSQL –第二部分:查询数据

在下面的内容中,您将学习如何准备WildFly以使其与Hibernate OGM一起使用,配置JPA持久性单元,创建用于访问数据的存储库类以及在这些之上提供REST资源。 在本文中,我们将主要关注与持久性相关的方面,因此使用REST / JAX-RS的一些基本经验可能会有所帮助。 本教程的完整源代码托管在GitHub上。

准备WildFly

WildFly服务器运行时基于JBoss Modules系统。 这提供了一个模块化的类加载环境,其中每个库(例如Hibernate OGM)都是其自己的模块,声明了它依赖的其他模块的列表,并且仅从那些其他依赖项中“看到”了类。 这种隔离使人们摆脱了可怕的“类路径地狱”。

SourceForge提供了包含Hibernate OGM所有必需模块的ZIP文件。 我们昨天发布的 Hibernate OGM 4.2支持WildFly 9,因此请下载hibernate-ogm-modules-wildfly9-4.2.0.Final.zip 。 如果您使用的是WildFly 8,请使用Hibernate OGM 4.1并获取hibernate-ogm-modules-wildfly8-4.1.3.Final.zip 。

将与您的WildFly版本相对应的归档文件解压缩到应用程序服务器的modules目录中。 如果您希望原始的WildFly目录保持不变,则还可以将Hibernate OGM模块存档解压缩到任何其他文件夹,并将其配置为服务器要使用的“模块路径”。 为此,请导出以下两个环境变量,以匹配您的特定环境:

export JBOSS_HOME=/path/to/wildfly
export JBOSS_MODULEPATH=$JBOSS_HOME/modules:/path/to/ogm/modules

如果您正在使用Maven WildFly插件 (例如在开发期间启动WildFly),则可以通过在POM文件中使用以下插件配置来实现相同的目的:

...
<plugin><groupId>org.wildfly.plugins</groupId><artifactId>wildfly-maven-plugin</artifactId><version>1.1.0.Alpha1</version><configuration><jboss-home>/path/to/wildfly</jboss-home><modules-path>/path/to/ogm/modules</modules-path></configuration>
</plugin>
...

设置项目

首先使用“ war”包装类型创建一个新的Maven项目。 将以下内容添加到您的pom.xml中

...
<dependencyManagement><dependencies><dependency><groupId>org.hibernate.ogm</groupId><artifactId>hibernate-ogm-bom</artifactId><type>pom</type><version>4.2.0.Final</version><scope>import</scope></dependency></dependencies>
</dependencyManagement>
...

这样可以确保获得匹配版本的Hibernate OGM模块和任何(可选)依赖项。 然后将依赖项添加到Java EE 7 API和Hibernate OGM后端模块之一,例如Infinispan ,JBoss的高性能,分布式键/值数据网格(其他任何诸如hibernate-ogm-mongodb或全新的hibernate -ogm-cassandra模块也可以工作):

...
<dependencies><dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version><scope>provided</scope></dependency><dependency><groupId>org.hibernate.ogm</groupId><artifactId>hibernate-ogm-infinispan</artifactId><scope>provided</scope></dependency>
</dependencies>
...

provided作用域使这些依赖项可用于编译,但是阻止将它们添加到生成的WAR文件中。 那是因为Java EE API已经是WildFly的一部分,而Hibernate OGM将通过您之前解压缩的模块来贡献。

但是,仅将这些模块添加到服务器并不会削减它。 还需要将它们注册为应用程序的模块依赖项。 为此,添加具有以下内容的文件src / main / webapp / WEB-INF / jboss-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structurexmlns="urn:jboss:deployment-structure:1.2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><deployment><dependencies><module name="org.hibernate" slot="ogm" services="import" /><module name="org.hibernate.ogm.infinispan" services="import" /><module name="org.hibernate.search.orm" services="import" /></dependencies></deployment>
</jboss-deployment-structure>

这将使Hibernate OGM核心和Infinispan后端以及Hibernate Search可用于您的应用程序。 后者将很快用于运行JP-QL查询。

添加实体类和存储库

有了基本的项目基础结构之后,就该添加实体类和存储库类以访问它们了。 实体类型基本上与第1部分中的相同,只是现在使用@Indexed进行注释,以允许它们通过Hibernate Search和Lucene进行查询:

@Entity
@Indexed
public class Person {@Id@GeneratedValue(generator = "uuid")@GenericGenerator(name = "uuid", strategy = "uuid2")private String id;private String firstName;private String lastName;@OneToMany(mappedBy = "organizer",cascade = { CascadeType.PERSIST, CascadeType.MERGE },fetch = FetchType.EAGER)private Set<Hike> organizedHikes = new HashSet<>();// constructors, getters and setters...
}
@Entity
@Indexed
public class Hike {@Id@GeneratedValue(generator = "uuid")@GenericGenerator(name = "uuid", strategy = "uuid2")private String id;private String description;private Date date;private BigDecimal difficulty;@ManyToOneprivate Person organizer;@ElementCollection(fetch = FetchType.EAGER)@OrderColumn(name = "sectionNo")private List<HikeSection> sections;// constructors, getters and setters...
}
@Embeddable
public class HikeSection {private String start;private String end;// constructors, getters and setters...
}

为了使用这些实体,必须定义一个JPA持久性单元。 为此,创建文件src / main / resources / META-INF / persistence.xml

<?xml version="1.0" encoding="utf-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"version="1.0"><persistence-unit name="hike-PU" transaction-type="JTA"><provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider><class>org.hibernate.ogm.demos.ogm101.part3.model.Person</class><class>org.hibernate.ogm.demos.ogm101.part3.model.Hike</class><properties><property name="hibernate.ogm.datastore.provider" value="INFINISPAN" /><property name="hibernate.ogm.datastore.database" value="hike_db" /><property name="hibernate.ogm.datastore.create_database" value="true" /></properties></persistence-unit>
</persistence>

在这里,我们定义一个名为“ hike-PU”的持久性单元。 Infinispan是一个完全事务性的数据存储,使用JTA作为事务类型可以使持久性单元参与容器管理的事务。 将HibernateOgmPersistence指定为提供程序类将启用Hibernate OGM(而不是Hibernate ORM),它已为设置后端(在这种情况下为INFINISPAN),数据库名称等配置了一些属性。

请注意,实际上,在Java EE容器(例如WildFly)中运行时,实际上不需要在persistence.xml中指定实体类型。 相反,它们应该被自动拾取。 使用Hibernate OGM时,目前很不幸。 这是一个已知的限制(请参阅OGM-828 ),我们希望尽快解决。

下一步是实现用于访问远足和组织者数据的存储库类。 例如,下面显示了PersonRepository类:

@ApplicationScoped
public class PersonRepository {@PersistenceContextprivate EntityManager entityManager;public Person create(Person person) {entityManager.persist( person );return person;}public Person get(String id) {return entityManager.find( Person.class, id );}public List<Person> getAll() {return entityManager.createQuery( "FROM Person p", Person.class ).getResultList();}public Person save(Person person) {return entityManager.merge( person );}public void remove(Person person) {entityManager.remove( person );for ( Hike hike : person.getOrganizedHikes() ) {hike.setOrganizer( null );}}
}

实现很简单; 通过@ApplicationScoped批注,该类被标记为应用程序范围的CDI bean(即,在应用程序的整个生命周期中都存在该bean的单个实例)。 它通过依赖注入获得JPA实体管理器,并使用该实体管理器来实现一些简单的CRUD方法(创建,读取,更新,删除)。

请注意, getAll()方法如何使用JP-QL查询返回所有人员对象。 执行后,此查询将转换为等效的Lucene索引查询,该查询将通过Hibernate Search运行。

远足资料库看起来非常相似,因此为简洁起见,在此省略。 您可以在GitHub上找到其源代码 。

公开REST服务

JAX-RS使构建基于REST的Web服务变得轻而易举。 它定义了一个声明式编程模型,您可以在其中注释简单的旧Java类,以提供HTTP端点的GET,POST,PUT等操作的实现。

深入描述JAX-RS超出了本教程的范围,例如,如果您想了解更多信息,请参考Java EE 7教程 。 让我们以资源类中用于管理人员的一些方法为例:

@Path("/persons")
@Produces("application/json")
@Consumes("application/json")
@Stateless
public class Persons {@Injectprivate PersonRepository personRepository;@Injectprivate ResourceMapper mapper;@Injectprivate UriMapper uris;@POST@Path("/")public Response createPerson(PersonDocument request) {Person person = personRepository.create( mapper.toPerson( request ) );return Response.created( uris.toUri( person ) ).build();}@GET@Path("/{id}")public Response getPerson(@PathParam("id") String id) {Person person = personRepository.get( id );if ( person == null ) {return Response.status( Status.NOT_FOUND ).build();}else {return Response.ok( mapper.toPersonDocument( person ) ).build();}}@GET@Path("/")public Response listPersons() { … }@PUT@Path("/{id}")public Response updatePerson(PersonDocument request, @PathParam("id") String id) { … }@DELETE@Path("/{id}")public Response deletePerson(@PathParam("id") String id) { … }
}

@Path@Produces@Consumes注释由JAX-RS所定义。 它们将资源方法绑定到特定的URL,以期望并创建基于JSON的消息。 @GET@GET @POST@GET @PUT@DELETE配置每个方法负责哪个HTTP动词。

@Stateless注释将此POJO定义为无状态会话Bean。 可以通过基于@Inject的依赖项注入来获取诸如PersonRepository的依赖项。 实现会话bean可以使您通过容器进行透明的事务管理。 Persons方法的调用将自动包装在一个事务中,并且Hibernate OGM与数据存储区的所有交互都将参与其中。 这意味着您对托管实体所做的任何更改(例如,通过PersonRepository#create()持久保存新人员或修改从实体管理器中检索到的Person对象)都将在方法调用返回后提交到数据存储中。

映射模型

请注意,我们的REST服务的方法不会返回并接受托管实体类型本身,而是返回特定的传输结构,例如PersonDocument

public class PersonDocument {private String firstName;private String lastName;private Set<URI> organizedHikes;// constructors, getters and setters...
}

这样做的理由是以URI的形式表示关联的元素( Person#organizedHikesHike#organizer ),这使客户端可以根据需要获取这些链接的资源。 例如,对http:// myserver / ogm-demo-part3 / hike-manager / persons / 123的GET调用可能返回如下JSON结构:

{"firstName": "Saundra","lastName": "Johnson","organizedHikes": ["http://myserver/ogm-demo-part3/hike-manager/hikes/456","http://myserver/ogm-demo-part3/hike-manager/hikes/789"]
}

内部模型(例如,实体Person )和外部模型(例如PersonDocument )之间的映射可能很快成为一项繁琐而枯燥的任务,因此需要一些基于工具的支持。 存在用于此工作的几种工具,其中大多数使用反射或运行时字节代码生成来在不同模型之间传播状态。

MapStruct寻求另一种方法,这是我的一个业余项目,并在编译时(例如,使用Maven或在您的IDE中)通过Java注释处理器生成bean映射器实现。 它生成的代码是类型安全的,快速的(它使用简单的方法调用,没有反射)并且没有依赖关系。 您只需要使用所需的源和目标类型的映射方法声明Java接口,MapStruct就会在编译过程中生成一个实现:

@Mapper(// allows to obtain the mapper via @InjectcomponentModel = "cdi",// a hand-written mapper class for converting entities to URIs; invoked by the generated// toPersonDocument() implementation for mapping the organizedHikes propertyuses = UriMapper.class
)
public interface ResourceMapper {PersonDocument toPersonDocument(Person person);List<PersonDocument> toPersonDocuments(Iterable<Person> persons);@Mapping(target = "date", dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")HikeDocument toHikeDocument(Hike hike);// other mapping methods ...
}

然后可以在Persons REST资源中使用生成的实现,以从内部模型映射到外部模型,反之亦然。 如果您想了解有关此模型映射方法的更多信息,请查看GitHub上的完整mapper界面或MapStruct参考文档 。

包起来

在我们的教程系列的这一部分中,您学习了如何将Hibernate OGM添加到WildFly应用程序服务器,并使用它来访问Infinispan作为小型REST应用程序的数据存储。

WildFly是使用Hibernate OGM的应用程序的绝佳运行时环境,因为它提供了现成的大多数必需的构建块(例如JPA / Hibernate ORM,JTA,事务管理等),并且紧密集成并可以使用。 我们的模块ZIP可以非常轻松地将Hibernate OGM模块放入组合中,而无需每次在您的应用程序中重新部署它们。 有了WildFly Swarm ,还支持微服务体系结构样式,但是我们将再留一点时间来展示如何将Hibernate OGM与Wildfly Swarm一起使用(当前,WildFly Swarm仍然缺少JPA支持)。

您可以在GitHub上找到该项目的源代码。 要构建项目,请运行mvn clean install (它使用Arquillian本身对一个激动人心的主题执行REST服务的集成测试 )。 另外,Maven WildFly插件可用于启动WildFly实例并通过mvn wildfly:run部署应用程序,这非常适合手动测试,例如通过curl或wget发送HTTP请求。

如果您有任何疑问,请在下面的评论中告诉我们,或给我们发送Tweet到@Hibernate 。 也欢迎您对本教程的后续部分的希望。 敬请关注!

翻译自: https://www.javacodegeeks.com/2015/06/nosql-with-hibernate-ogm-part-three-building-a-rest-application-on-wildfly.html

带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序相关推荐

  1. ogm session_带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序

    ogm session 欢迎回到我们的教程系列"带有Hibernate OGM的NoSQL"! 感谢Gunnar Morling( @gunnarmorling )创建了本教程. ...

  2. ogm session_带有Hibernate OGM的NoSQL –第一部分:持久化您的第一个实体

    ogm session Hibernate OGM的第一个最终版本已经发布 ,团队从发布狂潮中恢复了一些. 因此,他们考虑开设一系列教程风格的博客,使您有机会轻松地从Hibernate OGM重新开始 ...

  3. 带有Hibernate OGM的NoSQL –第一部分:持久化您的第一个实体

    Hibernate OGM的第一个最终版本已经发布 ,团队从发布狂潮中恢复了一些. 因此,他们考虑建立一系列教程式博客,使您有机会轻松地从Hibernate OGM重新开始. 感谢Gunnar Mor ...

  4. neo4j ogm_带有Hibernate OGM的NoSQL –第一部分:持久化您的第一个实体

    neo4j ogm Hibernate OGM的第一个最终版本已经发布,团队从发布狂潮中恢复了一些. 因此,他们考虑开设一系列教程风格的博客,使您有机会轻松地从Hibernate OGM重新开始. 感 ...

  5. 数据库 ogm_带有Hibernate OGM的NoSQL –第二部分:查询数据

    数据库 ogm Hibernate OGM的第一个最终版本发布于 1月底,团队一直在忙于制作一系列教程式博客,使您有机会轻松地从Hibernate OGM重新开始. 第一部分是关于设置和保留您的第一个 ...

  6. 带有Hibernate OGM的NoSQL –第二部分:查询数据

    1月底发布了Hibernate OGM的第一个最终版本之后,团队一直在忙于制作一系列教程式博客,使您有机会轻松地从Hibernate OGM重新开始. 第一部分是关于设置和保留您的第一个实体 . 在第 ...

  7. neo4j ogm_带有Hibernate OGM的NoSQL –第二部分:查询数据

    neo4j ogm 1月底发布了Hibernate OGM的第一个最终版本之后,团队一直在忙于制作一系列教程式博客,使您有机会轻松地从Hibernate OGM重新开始. 第一部分是关于设置和保留您的 ...

  8. paper weekly_Java Weekly 24/15:JCache,Hibernate OGM,微服务

    paper weekly 这篇文章最初出现在Thorben Janssen的Java EE博客上,每周都会发布Java新闻: Thoughts-on-java.org . JürgenHöller在他 ...

  9. NoSQL介绍(三)

    NoSQL介绍(三) Redis数据类型-string string为最简单的类型,与Memcached一样的类型,一个key对应一个value,其支持的操作与Memcached的操作类似,它的功能更 ...

最新文章

  1. RPM快速打包2017-08-21
  2. 云计算技术都要学什么?教你分清公有云、私有云和混合云
  3. 题目 1886: [蓝桥杯][2017年第八届真题]包子凑数(欧几里得+完全背包)
  4. Day-17: 网络编程
  5. [转载] python类运算符的重载
  6. ip_conntrack: table full, dropping packet的问题
  7. XML 反序列化为Model
  8. Python接口自动化-接口基础(二)
  9. Linux桌面虚拟化技术KVM
  10. 全栈性能测试修炼宝典jmeter实战电子版_推荐一款技术人必备的接口测试神器:Apifox...
  11. asp.net 母版页使用方法
  12. 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_7_常用的函数式接口_Supplier接口...
  13. linux 串口 数量限制,linux – 你的Unix的TTY主要数量是多少?
  14. 详解 Tree-structured Parzen Estimator(TPE)
  15. 「AI白身境」一文览尽计算机视觉研究方向
  16. 站长素材网 图标信息爬取(scrapy)
  17. 今天是微信7周年 7年之痒 一切都已被改变
  18. 日语在线学习网站简介
  19. mysql导出trigger_用mysqldump导出Trigger问题解决方法_MySQL
  20. [转载] 硬汉2奉陪到底

热门文章

  1. 在gitee上创建自己的仓库步骤
  2. JS中DOM节点的CRUD
  3. Hystrix---SpringCloud
  4. 数据结构树的基本操作_树的各类基本操作(数据结构)
  5. Spring boot(3):Spring boot中Redis 的使用
  6. spring使用自定义注解_用Spring组成自定义注释
  7. jdk open jdk_JDK 14的迹象开始出现
  8. JMetro版本5.2已发布
  9. 属性拼接转换成字符串_使用一些可选的将字符串配置属性转换为其他类型
  10. java 可视化_可视化Java 9模块关系