如何在Micronaut Reactive中正确处理DTO转换



假设我们正在使用Micronaut Reactive(Project Reactor(,我们想创建一个用户帐户。SignUp DTO由以下Kotlin类表示:

@Introspected
data class SignUpDto(
@field:Schema(example = "admin")
@field:NotBlank @field:Max(value = 255) var username: String? = null,
// rest is omitted for brevity
)

为了在数据库中创建并持久化帐户实体,首先,我们必须将SignUpDTO转换为由下面的kotlin类表示的帐户实体:

@Entity(name = "Accounts")
@Where("@.active = true")
open class AccountEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "accounts_sequence_generator")
@SequenceGenerator(name = "accounts_sequence_generator", sequenceName = "sequence_accounts")
@Column(name = "id", nullable = false, unique = true)
open var id: Long? = null
@Column(name = "username", nullable = false, unique = true, updatable = false, length = 255)
open var username: String? = null
@Column(name = "active", nullable = false)
open var active: Boolean? = true
@ManyToMany(fetch = FetchType.LAZY, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
@JoinTable(name = "accounts_roles",
joinColumns = [JoinColumn(name = "accounts", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "roles", referencedColumnName = "id")])
open var roles: MutableSet<RoleEntity> = mutableSetOf()
// rest is omitted for brevity
}

正如您所看到的,AccountEntity在RoleEntity上具有多对多关系。为了完整起见,RoleEntity如下所示:

@Entity(name = "Roles")
open class RoleEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", nullable = false, unique = true)
open var id: Long? = null
@Column(name = "role", nullable = false, unique = true)
@Enumerated(EnumType.STRING)
open var role: Role? = null
@Column(name = "description", nullable = false, length = 500)
open var description: String? = null
// rest is omitted for brevity
}

应用程序定义RoleRepository如下:

@Repository
interface RoleRepository : ReactorCrudRepository<RoleEntity, Long> {
fun findByRole(role: Role): Mono<RoleEntity>
}

我们感兴趣的是将SignUpDTO请求映射到帐户实体,并以响应方式持久化该实体。进行转换的函数如下所示:

fun convertSignUpToAccountEntity(@Valid signUpDto: SignUpDto): AccountEntity {
return AccountEntity().apply {
this.username = signUpDto.username
this.active = true
this.roles.add(**add a user role here**)
}
}

既然RoleRepository可用于此函数,那么如何获取Role.User实体并以响应方式将其添加到帐户角色列表中,因为调用块只是无限期地阻塞调用线程?有没有办法以被动的方式处理这个问题?

你可以有这样的东西:

return Flux.fromIterable(Arrays.asList("role1", "role2"))
.flatMap(role -> roleRepository.findByRole(role))
.collectList()
.map(roles -> convertSignUpToAccountEntity(signUpDto, roles))
.flatMap(accountEntityRepository::save);

最新更新