Spring R2DBC数据库客户端在PostgreSQL中执行自定义删除查询

k2arahey  于 2023-01-12  发布在  PostgreSQL
关注(0)|答案(1)|浏览(277)

嗨,我正在尝试从Postgres数据库的一个表中删除用户的ID。我正在使用Spring和R2DBC,并尝试使用DatabaseClient.execute("sqlCommand")进行自定义删除查询:

import org.springframework.data.r2dbc.core.DatabaseClient;

@Service
@Transactional
public class CustomSqlService {
    private final DatabaseClient databaseClient;

  public Mono<Void> deleteWithCustomSql(String sql) {
            databaseClient.execute(sql)
            return Mono.empty();
    }

其中sql等于"DELETE FROM user_table WHERE user_id = 1;"
控制器中的方法:

@RestController
@RequestMapping("postgres/")
@Timed
public class PostgresController {

// omitted code

   @DeleteMapping(path = "/delete_user/{userId}")
    public Mono<Void> deleteUser(@PathVariable("userId") Long userId)  {
       return customSqlService.deleteWithCustomSql("DELETE FROM user_table WHERE user_id = " + userId);
    }

但是当我测试它时,命令不起作用。当我调试时,我可以看到.execute()的结果中有MonoOnResumeError
我还有其他方法以同样的方式执行insertselect语句,它们工作得很好。
我对它的测试:

@Test
    void shouldDeleteDataFromTable() {
        User user = User.builder()
                .userId(1L)
                .sessionId(2L)
                .timestamp(10L)
                .build();

        webTestClient
                .post()
                .uri("/postgres/save_user")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .body(Mono.just(user), User.class)
                .exchange()
                .expectStatus().isOk()

     webTestClient
             .delete()
             .uri("/postgres/delete_user/1")
             .exchange()
             .expectStatus()
             .isOk();
      
        userRepository.findAll().take(1).as(StepVerifier::create)
                .expectNextCount(0)
                .verifyComplete();

如何在PostgreSQL中正确使用databaseClient.execute()进行自定义删除查询?

cbwuti44

cbwuti441#

希望您使用的是最新的R2 dbc 1.0和Spring Data R2 dbc(由Sping Boot 3.0管理)。
您的方法deleteWithCustomSql不起作用。databaseCLient.exectue上没有订阅,sql永远不会执行并返回结果。
尝试更改为以下内容,将sql移到此处,并使用bind将参数绑定到sql。

public Mono<Long> deleteByUserId(Long userId) {
     return databaseClient.sql("DELETE FROM user_table WHERE user_id = :userId")
         .bind("userId", userId)
         .fetch()
         .rowsUpdated();
}

在控制器中,更改为以下内容。

@DeleteMapping(path = "/users/{userId}")
public Mono<ResponseEntity> deleteUser(@PathVariable("userId") Long userId)  {
    return customSqlService.deleteByUserId(userId)
        .map(deleted -> {
            if(deleted>0) return noContent().build();
            else return notFound().build();
         });
}

检查我的delete操作的工作示例,它演示了如何在sql中绑定参数,它基于最新的Spring Data R2 dbc/Postgres。

相关问题