顶部横幅广告
您当前的位置:首页 > 创业指南

backordered,Spring Data Elasticsearch教程五

2022-10-24 01:45:08 本文共13556字,阅读本文大概需要27~45分钟
淘之家

原标题:Spring认证中国教育管理中心-Spring Data Elasticsearch教程五(Spring中国教育管理中心)

Spring Data Elasticsearch教程五

10. 实体回调

Spring Data 基础设施提供了在调用某些方法之前和之后修改实体的钩子。那些所谓EntityCallback的实例提供了一种方便的方式来检查和潜在地修改回调风格的实体。
AnEntityCallback看起来很像专门的ApplicationListener. BeforeSaveEvent一些 Spring Data 模块发布允许修改给定实体的存储特定事件(例如)。在某些情况下,例如在使用不可变类型时,这些事件可能会导致麻烦。此外,事件发布依赖于ApplicationEventMulticaster. 如果使用异步配置TaskExecutor它可能会导致不可预测的结果,因为事件处理可以分叉到线程上。

实体回调提供具有同步和反应式 API 的集成点,以保证在处理链中定义明确的检查点按顺序执行,返回可能修改的实体或反应式包装器类型。

实体回调通常按 API 类型分隔。这种分离意味着同步 API 只考虑同步实体回调,而反应式实现只考虑反应式实体回调。

Spring Data Commons 2.2 引入了实体回调 API。这是应用实体修改的推荐方式。在调用可能注册的实例之前ApplicationEvents,仍会发布特定于现有商店的信息。EntityCallback

10.1实现实体回调

AnEntityCallback通过其泛型类型参数直接与其域类型相关联。每个 Spring Data 模块通常附带一组EntityCallback涵盖实体生命周期的预定义接口。

示例 89. 解剖学 EntityCallback

@FunctionalInterfacepublic interface BeforeSaveCallback<T> extends EntityCallback<T> {/** * Entity callback method invoked before a domain object is saved. * Can return either the same or a modified instance. * * @return the domain object to be persisted. */T onBeforeSave(T entity <2>, String collection <3>); }

BeforeSaveCallback在保存实体之前调用的特定方法。返回一个可能修改过的实例。

在持久化之前的实体。

许多存储特定参数,例如实体持久保存到的集合。

示例 90. 反应式剖析 EntityCallback

@FunctionalInterfacepublic interface ReactiveBeforeSaveCallback<T> extends EntityCallback<T> {/** * Entity callback method invoked on subscription, before a domain object is saved. * The returned Publisher can emit either the same or a modified instance. * * @return Publisher emitting the domain object to be persisted. */Publisher<T> onBeforeSave(T entity <2>, String collection <3>); }

BeforeSaveCallback在保存实体之前,在订阅时调用的特定方法。发出一个可能修改过的实例。

在持久化之前的实体。

许多存储特定参数,例如实体持久保存到的集合。

可选的实体回调参数由实现的 Spring Data 模块定义,并从EntityCallback.callback().

实现适合您的应用程序需求的接口,如下例所示:

示例 91. 示例 BeforeSaveCallback

class DefaultingEntityCallback implements BeforeSaveCallback<Person>, Ordered {      @Overridepublic Object onBeforeSave(Person entity, String collection) {                   if(collection == "user") {    return // ...}return // ...}@Overridepublic int getOrder() {return 100;                                                                  }}

根据您的要求实现回调。

如果存在多个相同域类型的实体回调,则可能会订购实体回调。排序遵循最低优先级。

10.2.注册实体回调

EntityCallbackbean 被商店特定的实现拾取,以防它们在ApplicationContext. 大多数模板 API 已经实现ApplicationContextAware,因此可以访问ApplicationContext

以下示例说明了一组有效的实体回调注册:

示例 92. 示例EntityCallbackBean 注册

@Order(1)                                                           @Componentclass First implements BeforeSaveCallback<Person> {@Overridepublic Person onBeforeSave(Person person) {return // ...}}@Componentclass DefaultingEntityCallback implements BeforeSaveCallback<Person>,                                                           Ordered { @Overridepublic Object onBeforeSave(Person entity, String collection) {// ...}@Overridepublic int getOrder() {return 100;                                                  }}@Configurationpublic class EntityCallbackConfiguration {    @Bean    BeforeSaveCallback<Person> unorderedLambdaReceiverCallback() {           return (BeforeSaveCallback<Person>) it -> // ...    }}@Componentclass UserCallbacks implements BeforeConvertCallback<User>,                                        BeforeSaveCallback<User> {   @Overridepublic Person onBeforeConvert(User user) {return // ...}@Overridepublic Person onBeforeSave(User user) {return // ...}}

BeforeSaveCallback从@Order注释中接收它的命令。

BeforeSaveCallbackOrdered通过接口实现接收其订单。

BeforeSaveCallback使用 lambda 表达式。默认无序,最后调用。请注意,由 lambda 表达式实现的回调不会公开类型信息,因此使用不可分配的实体调用这些会影响回调吞吐量。使用classorenum为回调 bean 启用类型过滤。

在单个实现类中组合多个实体回调接口。

10.3.Elasticsearch EntityCallbacks

Spring Data Elasticsearch 在EntityCallback内部使用 API 来提供审计支持,并对以下回调做出反应:


Spring Data Elasticsearch教程五

11. Join-Type 实现

Spring Data Elasticsearch 支持Join 数据类型,用于创建相应的索引映射并存储相关信息。

11.1。设置数据

对于要在父子连接关系中使用的实体,它必须具有JoinField必须注释的类型属性。让我们假设一个Statement实体,其中的语句可能是问题答案评论投票(此示例中还显示了Builder,它不是必需的,但稍后在示例代码中使用):

@Document(indexName = "statements")@Routing("routing")                                                                       public class Statement {    @Id    private String id;    @Field(type = FieldType.Text)    private String text;    @Field(type = FieldType.Keyword)    private String routing;    @JoinTypeRelations(        relations =            {                @JoinTypeRelation(parent = "question", children = {"answer", "comment"}),                 @JoinTypeRelation(parent = "answer", children = "vote")                               }    )    private JoinField<String> relation;                                                       private Statement() {    }    public static StatementBuilder builder() {        return new StatementBuilder();    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getRouting() {        return routing;    }    public void setRouting(Routing routing) {        this.routing = routing;    }    public String getText() {        return text;    }    public void setText(String text) {        this.text = text;    }    public JoinField<String> getRelation() {        return relation;    }    public void setRelation(JoinField<String> relation) {        this.relation = relation;    }    public static final class StatementBuilder {        private String id;        private String text;        private String routing;        private JoinField<String> relation;        private StatementBuilder() {        }        public StatementBuilder withId(String id) {            this.id = id;            return this;        }        public StatementBuilder withRouting(String routing) {            this.routing = routing;            return this;        }        public StatementBuilder withText(String text) {            this.text = text;            return this;        }        public StatementBuilder withRelation(JoinField<String> relation) {            this.relation = relation;            return this;        }        public Statement build() {            Statement statement = new Statement();            statement.setId(id);            statement.setRouting(routing);            statement.setText(text);            statement.setRelation(relation);            return statement;        }    }}

有关路由相关信息,请参阅路由值

一个问题可以有答案和评论

一个答案可以有投票权

该JoinField属性用于将关系的名称(问题、答案、评论或投票)与父 ID 结合起来。泛型类型必须与带@Id注释的属性相同。

Spring Data Elasticsearch 将为此类构建以下映射:

{  "statements": {    "mappings": {      "properties": {        "_class": {          "type": "text",          "fields": {            "keyword": {              "type": "keyword",              "ignore_above": 256            }          }        },        "routing": {          "type": "keyword"        },        "relation": {          "type": "join",          "eager_global_ordinals": true,          "relations": {            "question": [              "answer",              "comment"            ],            "answer": "vote"          }        },        "text": {          "type": "text"        }      }    }  }}

11.2.存储数据

给定这个类的存储库,以下代码插入一个问题、两个答案、一个评论和一个投票:

void init() {    repository.deleteAll();    Statement savedWeather = repository.save(        Statement.builder()            .withText("How is the weather?")            .withRelation(new JoinField<>("question"))                                      .build());    Statement sunnyAnswer = repository.save(        Statement.builder()            .withText("sunny")            .withRelation(new JoinField<>("answer", savedWeather.getId()))                  .build());    repository.save(        Statement.builder()            .withText("rainy")            .withRelation(new JoinField<>("answer", savedWeather.getId()))                  .build());    repository.save(        Statement.builder()            .withText("I don't like the rain")            .withRelation(new JoinField<>("comment", savedWeather.getId()))                 .build());    repository.save(        Statement.builder()            .withText("+1 for the sun")            ,withRouting(savedWeather.getId())            .withRelation(new JoinField<>("vote", sunnyAnswer.getId()))                     .build());}

创建问题陈述

问题的第一个答案

第二个答案

对问题的评论

投票给第一个答案,这需要将路由设置为天气文档,请参阅路由值。

11.3.检索数据

目前,必须使用本机搜索查询来查询数据,因此标准存储库方法不支持。可以改为使用Spring Data Repositories 的自定义实现。

以下代码作为示例显示了如何使用实例检索所有有投票的条目(必须是answers,因为只有答案才能有投票)ElasticsearchOperations:

SearchHits<Statement> hasVotes() {    NativeSearchQuery query = new NativeSearchQueryBuilder()        .withQuery(hasChildQuery("vote", matchAllQuery(), ScoreMode.None))        .build();    return operations.search(query, Statement.class);}
飞马电商补单

本站文章、数据及图片如果侵犯了你的权益请来信告知我们删除。邮箱:1561406017@qq.com

飞马电商创业

飞马电商创业

当你还撑不起你的梦想时,就要去奋斗。如果缘分安排我们相遇,请不要让他擦肩而过。我们一起奋斗!

backordered,Spring Data Elasticsearch教程五

相关阅读