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

1月底发布了Hibernate OGM的第一个最终版本之后,团队一直在忙于制作一系列教程式博客,使您有机会轻松地从Hibernate OGM重新开始。 第一部分是关于设置和保留您的第一个实体 。 在第二部分中,您将学习如何查询数据。 Hibernate OGM将使您以几种不同的方式获取数据:

  • 使用Java持久性查询语言(JP-QL)
  • 使用您选择的数据存储的NoSQL本机查询语言(如果有的话)
  • 使用Hibernate Search查询–主要是全文查询

所有这些替代方案将使您可以在数据存储上运行查询,并以托管实体列表的形式获得结果。

准备测试课

我们将添加一个新的类HikeQueryTest。 它将使用有关加息的一些信息填充数据存储区:

public class HikeQueryTest {private static EntityManagerFactory entityManagerFactory;@BeforeClasspublic static void setUpEntityManagerFactoryAndPopulateTheDatastore() {entityManagerFactory = Persistence.createEntityManagerFactory( "hikePu" );EntityManager entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();// create a PersonPerson bob = new Person( "Bob", "McRobb" );// and two hikesHike cornwall = new Hike("Visiting Land's End", new Date(), new BigDecimal( "5.5" ),new HikeSection( "Penzance", "Mousehole" ),new HikeSection( "Mousehole", "St. Levan" ),new HikeSection( "St. Levan", "Land's End" ));Hike isleOfWight = new Hike("Exploring Carisbrooke Castle", new Date(), new BigDecimal( "7.5" ),new HikeSection( "Freshwater", "Calbourne" ),new HikeSection( "Calbourne", "Carisbrooke Castle" ));// let Bob organize the two hikescornwall.setOrganizer( bob );bob.getOrganizedHikes().add( cornwall );isleOfWight.setOrganizer( bob );bob.getOrganizedHikes().add( isleOfWight );// persist organizer (will be cascaded to hikes)entityManager.persist( bob );entityManager.getTransaction().commit();entityManager.close();}@AfterClasspublic static void closeEntityManagerFactory() {entityManagerFactory.close();}
}

此方法将确保在运行测试之前已创建实体管理器工厂,并且数据存储区包含一些数据。 数据与我们在第1部分中存储的数据相同。

现在我们已经有了一些数据,我们可以开始编写一些测试来搜索它们。

使用Java持久性查询语言(JP-QL)

JP-QL是一种查询语言,定义为Java Persistence API(JPA)规范的一部分 。 它旨在与实体一起使用并且独立于数据库。

以实体远足为例:

@Entity
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@OrderColumn(name = "sectionNo")private List<HikeSection> sections;// constructors, getters, setters, ...
}

JP-QL查询可获取按难度排序的可用加息列表,如下所示:

SELECT h FROM Hike h ORDER BY h.difficulty ASC

Hibernate OGM将解析此查询,并将其转换为您选择的数据存储区的本机查询语言中的等效查询。 例如,在Neo4j中,它创建并执行以下Cypher查询:

MATCH (h:Hike) RETURN h ORDER BY h.difficulty

在MongoDB中,使用MongoDB JavaScript API作为查询符号,它看起来像这样:

db.Hike.find({}, { "difficulty": 1})

如果在应用程序中使用JP-QL,则无需更新查询就可以在数据存储区之间切换。

现在您已经了解了所发生的情况,我们可以开始查询持久化的数据。 例如,我们可以获取可用加息的列表:

@Testpublic void canSearchUsingJPQLQuery() {// Get a new entityManagerEntityManager entityManager = entityManagerFactory.createEntityManager();// Start transactionentityManager.getTransaction().begin();// Find all the available hikes ordered by difficultyList<Hike> hikes = entityManager.createQuery( "SELECT h FROM Hike h ORDER BY h.difficulty ASC" , Hike.class ).getResultList();assertThat( hikes.size() ).isEqualTo( 2 );assertThat( hikes ).onProperty( "description" ).containsExactly( "Visiting Land's End", "Exploring Carisbrooke Castle" );entityManager.getTransaction().commit();entityManager.close();}

如果您曾经使用过JPA规范,就会发现此代码非常熟悉:这与使用JPA处理关系数据库时所编写的代码相同。

您可以通过在Neo4j和MongoDB之间切换配置和依赖项来进行测试:测试仍将通过而无需更改代码。

很棒的事情是,您可以对没有自己的查询引擎的数据存储使用JP-QL查询。 在这种情况下,Hibernate OGM的查询解析器将创建全文查询,这些查询通过Hibernate Search和Lucene执行。 稍后我们将详细介绍如何执行此操作。

查询的结果是被管理实体的列表。 这意味着对对象的更改将自动应用于数据库中的数据。 您还可以浏览结果对象图,从而根据需要加载惰性关联。

JP-QL语言的支持不完整,并且可能会因后端而异。 我们将把细节留给Hibernate的OGM官方文档。 目前支持的是:

  • 简单比较
  • IS NULLIS NOT NULL
  • 布尔运算符ANDORNOT
  • LIKE,INBETWEEN
  • 订购

如果JP-QL不适合您的用例,我们将了解如何使用所选后端的本机语言执行查询。

使用本机后端查询语言

有时,您可能决定牺牲可移植性,以支持基础本机查询语言的功能。 例如,您可能想从Neo4j的Cypher语言的功能中受益,以运行分层/递归查询。 使用MongoDB,让我们通过“ Penzance”进行加息:

// Search for the hikes with a section that start from "Penzace" in MongoDB
List<Hike> hikes = entityManager.createNativeQuery("{ $query : { sections : { $elemMatch : { start: 'Penzance' } } } }", Hike.class ).getResultList();

Neo4j的相同代码如下所示:

// Search for the hikes with a section that start from "Penzace" in Neo4j
List<Hike> hikes = entityManager.createNativeQuery( "MATCH (h:Hike) -- (:Hike_sections {start: 'Penzance'} ) RETURN h", 
Hike.class ).getResultList();

需要注意的重要一点是,与JPA查询一样,查询返回的对象是托管实体。

您还可以使用注释javax.persistence.NamedNativeQuery定义查询:

@Entity
@NamedNativeQuery(
name = "PenzanceHikes",
query = "{ $query : { sections : { $elemMatch : { start: 'Penzance' } } } }", resultClass = Hike.class )
public class Hike { ... }

然后像这样执行它:

List<Hike> hikes = entityManager.createNamedQuery( "PenzanceHikes" ).getResultList();

使用Hibernate Search查询

Hibernate Search提供了一种将Java对象索引到Lucene索引中并对其执行全文查询的方法。 索引确实位于数据存储区之外。 这意味着即使本机不支持查询功能,也可以具有查询功能。 它还在功能集和可伸缩性方面提供了一些有趣的属性。 特别是,使用Hibernate Search,您可以减轻查询执行的负担,以分离节点并独立于实际的数据存储节点进行扩展。

在此示例中,我们将使用MongoDB。 您首先需要将Hibernate Search添加到您的应用程序。 在Maven项目中,您需要在pom.xml中添加以下依赖项:

<dependencies>...<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-search-orm</artifactId></dependency>...
</dependencies>

现在,您可以选择要索引的内容:

@Entity
@Indexed
public class Hike {@Id@GeneratedValue(generator = "uuid")@GenericGenerator(name = "uuid", strategy = "uuid2")private String id;@Fieldprivate String description;private Date date;private BigDecimal difficulty;@ManyToOneprivate Person organizer;@ElementCollection@OrderColumn(name = "sectionNo")private List<HikeSection> sections;// constructors, getters, setters, ...
}

@Indexed注释标识我们要索引的类,而@Field注释指定我们要索引的类的属性。 每当使用Hibernate OGM通过实体管理器保留新的Hike实体时,Hibernate Search都会自动将其添加到索引中并跟踪对托管实体的更改。 这样,索引和数据存储就可以保持最新状态。

您现在可以使用Lucene查询来寻找Carisbrooke的远足。 在此示例中,我们将使用Hibernate Search提供的查询构建器:

@Test
public void canSearchUsingFullTextQuery() {EntityManager entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();//Add full-text superpowers to any EntityManager:FullTextEntityManager ftem = Search.getFullTextEntityManager(entityManager);// Optionally use the QueryBuilder to simplify Query definition:QueryBuilder b = ftem.getSearchFactory().buildQueryBuilder().forEntity( Hike.class ).get();// A Lucene query to search for hikes to the Carisbrooke castle:Query lq = b.keyword().onField("description").matching("Carisbrooke castle").createQuery();//Transform the Lucene Query in a JPA Query:FullTextQuery ftQuery = ftem.createFullTextQuery(lq, Hike.class);//This is a requirement when using Hibernate OGM instead of ORM:ftQuery.initializeObjectsWith( ObjectLookupMethod.SKIP, DatabaseRetrievalMethod.FIND_BY_ID );// List matching hikesList<Hike> hikes = ftQuery.getResultList();assertThat( hikes ).onProperty( "description" ).containsOnly( "Exploring Carisbrooke Castle" );entityManager.getTransaction().commit();entityManager.close();
}

代码的结果将是描述中提到“ Carisbrooke城堡”的远足清单。

Hibernate Search是一个非常强大的工具,具有许多不同的选项,在本教程中描述所有这些选项都将花费很长时间。 您可以查看参考文档以了解更多信息。

包起来

目前为止就这样了。 如您所见,Hibernate OGM为您提供了一系列对数据存储区运行查询的选项,这些选项应满足您大多数典型的查询需求:JP-QL,本机NoSQL查询和通过Hibernate Search / Apache Lucene进行的全文查询。 即使您以前从未使用过NoSQL数据存储区,也可以轻松地对其进行试验。

您可以在GitHub上找到此博客文章(以及上一篇)的完整示例代码 。 只需叉子,然后随心所欲地玩就可以了。

现在您已经知道如何存储和查找实体,在本系列的下一部分中,我们将看到如何将所有内容放入WildFly之类的应用程序容器中。

我们渴望了解您的意见,随时发表评论或与我们联系 ,我们将回答您的问题并听到您的反馈。

感谢Gunnar Morling( @gunnarmorling )和Davide D'Alto(@Github: DavidD )创建了本教程。

翻译自: https://www.javacodegeeks.com/2015/02/nosql-hibernate-ogm-part-two-querying-data.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux下做一个arp欺骗程序6,LINUX下防ARP欺骗攻击

arp欺骗的原理不多述&#xff0c;基本就是利用发送假的arp数据包&#xff0c;冒充网关。一般在网上通讯的时候网关的IP和MAC的绑定是放在arp 缓存里面的&#xff0c;假的arp包就会刷新这个缓存&#xff0c;导致本该发送到网关的数据包发到了欺骗者那里。解决的办法就是静态arp。…

MySQL作为Kubernetes服务,可从WildFly Pod访问

Kubernetes上使用Vagrant的Java EE 7和WildFly&#xff08;技术提示&#xff03;71&#xff09;介绍了如何在使用Kubernetes和Docker托管的WildFly上运行琐碎的Java EE 7应用程序。 Java EE 7应用程序是在世界范围内交付的动手实验室 。 它使用与WildFly捆绑在一起的内存数据库…

几个最短路径算法Floyd、Dijkstra、Bellman-Ford、SPFA的比较

几大最短路径算法比较 转自&#xff1a;http://blog.csdn.net/v_july_v/article/details/6181485 几个最短路径算法的比较&#xff1a;Floyd 求多源、无负权边的最短路。用矩阵记录图。时效性较差&#xff0c;时间复杂度O(V^3)。 Floyd-Warshall算法&#xff08;Floyd-W…

linux系统creat函数,Linux系统调用之creat函数

Linux中系统调用很多&#xff0c;但是再多也有几种不变的根本&#xff1a;创建&#xff0c;打开&#xff0c;写&#xff0c;读&#xff0c;关闭&#xff0c;删除&#xff0c;等最最基本的操作&#xff0c;就像人们所常说的&#xff0c;Linux上的一切我们都可以当做文件来处理&a…

防止在多模块Maven中找到“未找到插件”

在多模块Maven项目的子模块上定义Maven插件会给我们“找不到插件”错误。 尤其是如果我们有一个多模块项目&#xff0c;并且只想在一个特定模块中应用Maven插件&#xff0c;则此错误会经常发生。 假设我们有一个看起来像这样的多模块root pom。 <project xmlns"http:…

linux 4412跑程序,荣品4412的板子上跑纯linux

昨天开始突然想在4412上面跑人QT玩&#xff0c;首先得跑个纯linux昨天做好第一步&#xff0c;把根文件系统&#xff0c;用make_ext4fs 打包。make_ext4fs -l 34M -s system.img minifs/然后在uboot启动命令中把启动参数修改&#xff1a;setenv bootargs noinitrd root/dev/mmcb…

ASP.NET MVC 笔记

&#xff08;从今天开始&#xff0c;还是换回默认的代码高亮插件吧。。。话说此篇仅供个人遗忘后查阅&#xff0c;木有详尽解释。。。&#xff09; 1、Controller中的所有Action方法不限制返回值类型&#xff0c;返回值应该至少可以被ToString()&#xff0c;这样最终页面上呈现…

JPA 2.1:不同步的持久性上下文

JPA 2.1版带来了一种新的方式来处理持久性上下文与当前JTA事务以及资源管理器之间的同步。 术语资源管理器来自Java事务处理API &#xff0c;它表示操纵一个资源的组件&#xff08;例如&#xff0c;使用JDBC驱动程序操纵的具体数据库&#xff09;。 默认情况下&#xff0c;容器…

麒麟Linux启动目录,优麒麟目录结构介绍 系统入门必备

对于Linux爱好者来说&#xff0c;深入了解Linux文件目录结构的标准和每个目录的详细功能&#xff0c;对于我们用好Linux系统至关重要&#xff0c;下面就由小编给大家介绍下优麒麟系统的目录结构&#xff0c;PS: 同样适用于其他Linux发行版。查看系统的全部目录&#xff1a;* 在…

java课堂作业(一)

1、环境变量配置参见&#xff1a;http://www.cnblogs.com/dongwenbo/p/3282014.html window ---> preference ---> java ---> installed jres ---> add jres tomcat 配置&#xff1a;myeclipse ---> preferences ---> myeclipse enterprise workbench --->…

为什么我的JVM访问的内存少于通过-Xmx指定的内存?

“嘿&#xff0c;你能来看看奇怪的东西吗&#xff1f;” 这就是我开始研究一个支持案例的方式&#xff0c;该案例将我引向了这篇博客文章。 当前的特殊问题与不同的工具报告了有关可用内存的不同数字有关。 简而言之&#xff0c;一位工程师正在研究特定应用程序的过多内存使用…

linux怎么安装高德导航软件,高德地图车机版如何安装?高德地图车机版安装教程...

高德地图车机版是高德为汽车车载机提供的一个专用版本&#xff0c;对于车主们来说有时候用手机导航实在是非常不方便&#xff0c;不仅屏幕小而且还可能中途来个电话什么的。高德地图车机版可以帮你的车载机装上导航地图&#xff0c;就算你不想买导航设备也能让你的车子为你导航…

SharePoint 2010 技术参数(整理)

今天整理一些 SharePoint 2010 的技术参数&#xff0c;其内容都来自 SharePoint-Sandbox 网站。 有些参数值是硬性的&#xff0c;比如列表单条记录的尺寸&#xff1b;而有些是为了使用和性能考虑的推荐值。 技术参数值列表最大记录数500万条列表单条记录上限8KB&#xff08;不含…

Dropwizard,MongoDB和Gradle实验

介绍 我使用Dropwizard&#xff0c;MongoDB和Gradle创建了一个小项目。 它实际上是从一个实验性的Guava缓存开始的&#xff0c;作为将计数器发送到MongoDB&#xff08;或任何其他DB&#xff09;的缓冲区。 我也想尝试MondleDB插件的Gradle。 接下来&#xff0c;我想创建某种接口…

linux eclipse svn插件安装,Linux上Eclipse安装SVN插件和安装JavaHL

在Eclipse上安装svn插件有两种选择&#xff0c;一种是Subclipse&#xff0c;一种是Eclipse Subversion。前者是svn的官网eclipse插件&#xff0c;后者是eclipse的官方svn插件&#xff0c;具体有什么不同我也不算很清楚&#xff0c;想知道的请自行百度。网上建议用Subclipse&…

用apache的httpclient发请求和接受数据

此处发请求的是用httpclient4,请自己下载所需要的jar包。 发post请求&#xff0c;并得到数据。 String url "http://localhost:8080/lee";url url "/query/action/export.action";String exportFilePath "lee"".csv.";final HttpCl…

使用Flyway在Java EE中进行数据库迁移

任何Java EE应用程序的数据库模式都会随着业务逻辑一起发展。 这使得数据库迁移对于任何Java EE应用程序都非常重要。 您是否还在执行应用程序时手动执行它们&#xff1f; 它仍然是一个锁定步骤过程&#xff0c;还是作为两个单独的脚本运行–一个用于应用程序部署&#xff0c;…

suse linux安装rpm包,linux – 如何为Suse创建RPM

重建现有的src.rpm可能是最简单的.我肯定不会采用configure,make,make install的方式,因为(a)不能扩展,(b)不提供容易删除/升级包和(c)不是原子的.建立RPM并不是那么难.在他们销毁网站之前,Linux.com上曾经有一个非常好的初学者教程.你可以尝试这个one,但这是很多文字,不容易消…

在wp中,使用NavigationService.Navigate导航页面出现错误

我们在WP项目中采用页面导航时候&#xff0c;经常会使用以下代码 NavigationService.Navigate(new Uri("/Page1.xaml",UriKind.Relative));但是&#xff0c;有的时候会出现错误&#xff1a; "Error 1 An object reference is required for the non-static field…

linux iso合并,把RedHat Linux 5.0的CD ISO合并成DVD的脚本

最近找RedHat Linux5.0 x86_64的DVD ISO文件&#xff0c;结果一直找不到&#xff0c;却找到了6个cd的ISO&#xff0c;因为最后一个为源码盘&#xff0c;暂时不管&#xff0c;把其他5个CD合并成一个DVD。脚本如下&#xff1a;vim dvd.sh#!/bin/bash# by Chris Kloiber# A quick …