0

我正在 Kotlin 和 Quarkus 中创建一个应用程序。我现在正在创建一个通用的休息资源,它将由我的其他资源类扩展。我的想法是我将不得不编写更少的代码,因为泛型类的所有方法都将被其子类使用。现在我遇到的问题是传递一个通用的 PanacheRepository。

GenericResource 中的所有方法都使用 PanacheRepository 方法。但是,当我尝试通过构造函数将例如 UserRepository 传递给 GenericResource 时,它​​不起作用。

下面是我的通用资源:

class GenericResource(
    val repository: PanacheRepository<Any>
    ) {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    fun findAll() : FindAllResponse =
        try {
            FindAllSuccess(repository.listAll())
        } catch (e: Exception) {
            FindAllFailure(e)
        }

    @POST
    @Transactional
    fun add(
        @Valid user: User
    ) : AddResponse =
        try {
            repository.persist(user)
            AddSuccess(user)
        } catch (e: Exception) {
            AddFailure(e)
        }

    @GET
    @Path("/{userId}")
    fun findById(
        @PathParam("userId")
        userId : UUID
    ) : FindResponse =
        try {
            FindSuccess(
                repository.find("id", userId).firstResult()
            )
        } catch (e: NotFoundException) {
            FindFailure(e)
        }

    @PATCH
    @Transactional
    @Path("/{userId}")
    fun update(
        @PathParam("userId")
        userId : UUID,
        user: User
    ) : UpdateResponse =
        try {
            user.id?.let { user.fullName?.let { it1 ->
                user.email?.let { it2 ->
                    repository.update("fullName = ?1, email = ?2 where id = ?3",
                        it1, it2, it)
                }
            } }
            UpdateSuccess(user)
        } catch (e: Exception) {
            UpdateFailure(e)
        }

    @DELETE
    @Transactional
    @Path("/{userId}")
    fun delete(
        @PathParam("userId")
        userId : UUID
    ) : DeleteResponse =
        try {
            repository.delete("id", userId)
            DeleteSuccess("User deleted.")
        } catch (e: Exception) {
            DeleteFailure(e)
        }

}

这将是我的 UserResource:

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class UserRes(user: User) : GenericResource(user) {
}

我还有一个单独的 UserRepository 是这样的:

@ApplicationScoped
class UserRepository : PanacheRepository<User>

有人能把我推向正确的方向吗?对 Kotlin 还是很陌生 :)

4

1 回答 1

0

我找到了答案。通过使用泛型,我可以将我的实体传递给 GenericResource:

open class GenericResource<T : Any>(
    @ApplicationScoped
    private var repository: PanacheRepository<T>
    ) {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    fun findAll() : FindAllResponse =
        try {
            FindAllSuccess(repository.listAll())
        } catch (e: Exception) {
            FindAllFailure(e)
        }

    @POST
    @Transactional
    fun add(
        @Valid resource: T
    ) : AddResponse =
        try {
            repository.persist(resource)
            AddSuccess(resource)
        } catch (e: Exception) {
            AddFailure(e)
        }

    @GET
    @Path("/{id}")
    fun findById(
        @PathParam("id")
        id : UUID
    ) : FindResponse =
        try {
            FindSuccess(
                repository.find("id", id).firstResult()
            )
        } catch (e: NotFoundException) {
            FindFailure(e)
        }

    @PUT
    @Transactional
    @Path("/{id}")
    fun update(
        @PathParam("id")
        id : UUID,
        resource: T
    ) : UpdateResponse =
        try {
            repository.persist(resource)
            UpdateSuccess(resource)
        } catch (e: Exception) {
            UpdateFailure(e)
        }

    @DELETE
    @Transactional
    @Path("/{id}")
    fun delete(
        @PathParam("id")
        id : UUID
    ) : DeleteResponse =
        try {
            repository.delete("id", id)
            DeleteSuccess("User deleted.")
        } catch (e: Exception) {
            DeleteFailure(e)
        }

}

以及将使用它的 UserResource:

@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class UserResource(user: UserRepository) : GenericResource<User>(user)
于 2021-08-27T12:58:24.180 回答