如何使用 r2dbc @Query 正确编写三个值选项的查询: true、false、null ? (postgresql)

问题描述 投票:0回答:2

我正在尝试发出请求以从数据库获取数据

参数中包含三个选项的布尔值:

  1. false - 显示带有 false 的实体
  2. true - 显示 true 的实体
  3. null - 与 user_id 对应的任何选项

但我不知道如何处理 null

@Repository
public interface Repo extends ReactiveCrudRepository<Device,Long> {

    @Query("SELECT * FROM device where user_id = $1 and show = $2")
    Flux<Device> findByUserIdAndShow(String userId, Boolean show);

}
java postgresql spring-boot spring-webflux r2dbc
2个回答
0
投票
@Query("SELECT * FROM device where user_id = $1 and ($2 is null or show = $2)")

0
投票

我更喜欢创建简单的无条件本机查询并将业务逻辑放入默认方法中,该方法充当中央“开关”。

public interface Repo extends ReactiveCrudRepository<Device,Long> {
    @Query("SELECT * FROM device WHERE user_id = :userId AND show = :show")
    Flux<Device> doFindByUserIdAndShow(@NonNull String userId, boolean show);

    @Query("SELECT * FROM device WHERE user_id = :userId")
    Flux<Device> findByUserId(@NonNull String userId);

    default Flux<Device> findByUserIdAndShow(@NonNull String userId, @Nullable Boolean show) {
        if (show == null) {
            return findByUserId(String userId);
        }
        return findByUserIdAndShow(userId, show);
    }
}

在您的特定情况下,它不会产生很大的差异,但它通常会产生更可读的 SQL 并为您提供更好的灵活性。

想象一下这样一种情况,当你有一个表,其ID默认由数据库生成,但有时你需要通过Java代码生成ID,例如

CREATE TABLE mail
(
    id uuid DEFAULT uuid_generate_v1() NOT NULL PRIMARY KEY,
    received timestamp with time zone NOT NULL,
    sender text NOT NULL,
    subject text NOT NULL,
    ...
);

那么实体定义为

@Data
@Builder
@Table("mail")
public class MailEntity {
    UUID id;
    Instant received;
    String sender;
    String subject;
    ...
}

并且您想要实现一个

insertMail()
来正确处理带有和不带有
id
的实体。是的,我们有一个它的用例,因为有时电子邮件是在我们的微服务内部创建的,有时是在外部创建的,并且由于 UUID 是主键,我们可以将它们存储在单个表中。

所以存储库看起来像这样

// Postgres SQL dialect
public interface MailRepository extends R2dbcRepository<MailEntity, UUID> {
    @Query("""
            INSERT INTO mail(id, received, sender, subject, ...)
                VALUES (
                    :#{#mail.id},
                    :#{#mail.received},
                    :#{#mail.sender},
                    :#{#mail.subject},
                    ...
                RETURNING *
            """)
    Mono<MailEntity> insertMailWithId(MailEntity mail);

    @Query("""
            INSERT INTO mail(received, sender, subject, ...)
                VALUES (
                    :#{#mail.received},
                    :#{#mail.sender},
                    :#{#mail.subject},
                    ...
                RETURNING *
            """)
    Mono<MailEntity> insertMailWithoutId(MailEntity mail);

    default Mono<MailEntity> insertMail(MailEntity mail) {
        if (mail.getId() == null) {
            return insertMailWithoutId(mail);
        }
        return insertMailWithId(mail);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.