1

spring-data-r2dbc を試しています。Postgresqlでこれを試しています。以前に spring-data-mongodb-reactive を試しました。思わず両方を見比べてしまいました。

クエリ派生はまだサポートされていないようです。しかし、に相当するものがあるかどうか疑問に思っていました@Tailable。このようにして、データベースの変更がリアルタイムで通知されます。これに関して、誰でもコードサンプルを共有できますか?

基礎となるデータベースがこれをサポートする必要があることを理解しています。Postgresqlは、論理デコードを使用してこの種のことをサポートしていると思います(ここで間違っている場合は修正してください)。

@Tailablespring-data-r2dbc に相当するものはありますか?

4

1 に答える 1

4

解決策が見つかったかどうかはわかりませんが、次のことを行うことで同様のことを達成できました。まず、トリガーをテーブルに追加しました

CREATE TRIGGER trigger_name
    AFTER INSERT OR DELETE OR UPDATE 
    ON table_name
    FOR EACH ROW
    EXECUTE PROCEDURE trigger_function_name;

これにより、行が更新、削除、または挿入されるたびにテーブルにトリガーが設定されます。次に、設定したトリガー関数を呼び出します。これは次のようになります。

CREATE FUNCTION trigger_function_name
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS 
$BODY$
DECLARE
    payload JSON;
BEGIN
    payload = row_to_json(NEW);
    PERFORM pg_notify('notification_name', payload::text);
    RETURN NULL;
END;
$BODY$;

これにより、Spring Boot プロジェクトからのこれらの更新のいずれかを「聞く」ことができ、行全体がペイロードとして送信されます。次に、Spring Boot プロジェクトで、データベースへの接続を構成しました。

@Configuration
@EnableR2dbcRepositories("com.(point to wherever repository is)")
public class R2DBCConfig extends AbstractR2dbcConfiguration {
    @Override
    @Bean
    public ConnectionFactory connectionFactory() {
        return new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder()
                .host("host")
                .database("db")
                .port(port)
                .username("username")
                .password("password")
                .schema("schema")
                .connectTimeout(Duration.ofMinutes(2))
                .build());
    }
}

それを使用して、サービス クラスのコンストラクターに Autowire (依存性注入) し、次のように r2dbc PostgressqlConnection クラスにキャストします。

this.postgresqlConnection = Mono.from(connectionFactory.create()).cast(PostgresqlConnection.class).block();

ここで、テーブルを「リッスン」して、テーブルに何らかの更新を実行したときに通知を受け取りたいと考えています。そのために、 @PostContruct アノテーションを使用して依存性注入後に実行される初期化メソッドをセットアップします

@PostConstruct
private void postConstruct() {
    postgresqlConnection.createStatement("LISTEN notification_name").execute()
            .flatMap(PostgresqlResult::getRowsUpdated).subscribe();
}

pg_notify メソッド内に入力した名前をリッスンしていることに注意してください。また、次のように、Bean が捨てられようとしているときに接続を閉じるメソッドを設定したいと考えています。

@PreDestroy
private void preDestroy() {
    postgresqlConnection.close().subscribe();
}

ここで、現在テーブルにあるものの Flux を返すメソッドを作成するだけで、通知が json として入る前に述べたように、それを通知とマージするので、逆シリアル化する必要があり、使用することにしましたオブジェクトマッパー。したがって、次のようになります。

private Flux<YourClass> getUpdatedRows() {
    return postgresqlConnection.getNotifications().map(notification -> {
        try {
            //deserialize json
            return objectMapper.readValue(notification.getParameter(), YourClass.class);
        } catch (IOException e) {
            //handle exception
        }
    });
}

public Flux<YourClass> getDocuments() {
    return documentRepository.findAll().share().concatWith(getUpdatedRows());
}

お役に立てれば。乾杯!

于 2020-05-15T17:03:28.877 に答える