做公司网站流程,专业的销售网站,心雨在线高端网站建设,33岁改行做网站建设1月底发布了Hibernate OGM的第一个最终版本之后#xff0c;团队一直在忙于制作一系列教程式博客#xff0c;使您有机会轻松地从Hibernate OGM重新开始。 第一部分是关于设置和保留您的第一个实体 。 在第二部分中#xff0c;您将学习如何查询数据。 Hibernate OGM将使您以几… 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 Lands End, new Date(), new BigDecimal( 5.5 ),new HikeSection( Penzance, Mousehole ),new HikeSection( Mousehole, St. Levan ),new HikeSection( St. Levan, Lands 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 APIJPA规范的一部分 。 它旨在与实体一起使用并且独立于数据库。 以实体远足为例 Entity
public class Hike {IdGeneratedValue(generator uuid)GenericGenerator(name uuid, strategy uuid2)private String id;private String description;private Date date;private BigDecimal difficulty;ManyToOneprivate Person organizer;ElementCollectionOrderColumn(name sectionNo)private ListHikeSection 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 difficultyListHike 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 Lands 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 NULL和IS NOT NULL 布尔运算符AND OR NOT LIKEIN和BETWEEN 订购 如果JP-QL不适合您的用例我们将了解如何使用所选后端的本机语言执行查询。 使用本机后端查询语言 有时您可能决定牺牲可移植性以支持基础本机查询语言的功能。 例如您可能想从Neo4j的Cypher语言的功能中受益以运行分层/递归查询。 使用MongoDB让我们通过“ Penzance”进行加息 // Search for the hikes with a section that start from Penzace in MongoDB
ListHike 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
ListHike 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 { ... } 然后像这样执行它 ListHike hikes entityManager.createNamedQuery( PenzanceHikes ).getResultList(); 使用Hibernate Search查询 Hibernate Search提供了一种将Java对象索引到Lucene索引中并对其执行全文查询的方法。 索引确实位于数据存储区之外。 这意味着即使本机不支持查询功能也可以具有查询功能。 它还在功能集和可伸缩性方面提供了一些有趣的属性。 特别是使用Hibernate Search您可以减轻查询执行的负担以分离节点并独立于实际的数据存储节点进行扩展。 在此示例中我们将使用MongoDB。 您首先需要将Hibernate Search添加到您的应用程序。 在Maven项目中您需要在pom.xml中添加以下依赖项 dependencies...dependencygroupIdorg.hibernate/groupIdartifactIdhibernate-search-orm/artifactId/dependency...
/dependencies 现在您可以选择要索引的内容 Entity
Indexed
public class Hike {IdGeneratedValue(generator uuid)GenericGenerator(name uuid, strategy uuid2)private String id;Fieldprivate String description;private Date date;private BigDecimal difficulty;ManyToOneprivate Person organizer;ElementCollectionOrderColumn(name sectionNo)private ListHikeSection 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 hikesListHike 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 DAltoGithub DavidD 创建了本教程。 翻译自: https://www.javacodegeeks.com/2015/02/nosql-hibernate-ogm-part-two-querying-data.html