jpa如何在多个关系中给定一个对象来查询@onetomany关系

d5vmydt9  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(338)

我看到了一些相关的问题,但我似乎找不到正确的答案,我正在努力做什么。我有两个表作业和工人,一个作业可以有很多工人,简化实体

@Entity
@Table(name = "jobs")
data class Job(
    @Id
    @Type(type = "pg-uuid")
    val id: UUID = UUID.randomUUID()
) {
    @ManyToOne
    var office: Office? = null

    @OneToMany(targetEntity = Worker::class)
    var requests: MutableList<Worker> = mutableListOf()
}

我希望能够获取特定工人的工作列表
我试过一些本地的和非本地的查询,但是现在试着用namedmethods来做,我想说实话,不管是什么样的方法,在我的工作报告中都应该是有效的

@Repository
interface JobsRepo : CrudRepository<Job, UUID> {

    @Query("SELECT j FROM Job j WHERE id = ?1")
    fun findJobById(id: UUID): Job?

    @Query("SELECT j FROM Job j WHERE office_id = ?1")
    fun findJobsByOffice(id: UUID): List<Job>?

    @Modifying
    @Transactional
    @Query("UPDATE jobs SET job_status = 4 WHERE job_status = 1 AND start_time < ?1", nativeQuery = true)
    fun expireJobs(date: Date)

    fun findByRequests_Worker(worker: Worker): List<Job>?

}

我不确定如何查询数组属性

requests

一个工人的投入。我也尝试过查询worker的uuid,因为这是join表中的内容
jpa创建了一个包含两个外键的连接表

jobs_requests

和列

job_id UUID
requests_id UUID
qgzx9mmu

qgzx9mmu1#

你提到了一个工作可以有很多工人,你还提到你想得到一个特定工人的工作列表。所以这听起来像是一种多人的关系而不是一个人的关系。
对于多对多关系,连接表是不可避免的。您需要在这两个实体上指定@manytomany注解,然后可以使用workerrepository查询worker,然后获取该worker的作业列表,您只需要按worker.getjobs()访问即可。
以下是manytomany关系的设置,希望能有所帮助:

@Entity
@Table(name = "jobs")
data class Job (
    @ManyToMany
    @get:ManyToMany
    @get:JoinTable(
            name = "worker_job",
            joinColumns = [JoinColumn(name = "job_id")],
            inverseJoinColumns = [JoinColumn(name = "worker_id")]
    )
    val worker: Set<Worker> = HashSet()

)
@Entity
@Table(name = "worker")
data class Worker (
    @ManyToMany
    @get:ManyToMany
    @get:JoinTable(
            name = "worker_job",
            joinColumns = [JoinColumn(name = "worker_id")],
            inverseJoinColumns = [JoinColumn(name = "job_id")]
    )
     val jobs: Set<Jobs> = HashSet()
)
lnxxn5zx

lnxxn5zx2#

同样值得注意的是,对于所有实际应用,您应该尽量避免显式的manytomy注解。您应该创建一个新的实体/表,其中包含job和worker的字段,这两个字段都与各自的实体有多个关联。
您应该避免显式manytomy的原因是,假设有一个特定的作业,例如javadev,并且给定的作业上有1000个工人。有一次,你有一个javadev实体,你想得到所有年龄在20到25岁之间的工人。要做到这一点,需要迭代作为javadev实体一部分的workers列表并过滤掉它们。当这种情况发生时,有两种情况:
workers列表是一个延迟关联,当您尝试访问它时,hibernate将向数据库发送1000个(n+1个问题)查询。
workers list是一个急切的关联,hibernate将向数据库发送相同数量的查询,但是只要您尝试获取javadev实体。
因此,执行时间会增加,因为数据库本身会有不必要的负载量。而在更大的项目上,这将变得更加复杂。
如果您创建自己的manytomy(job\u workers for ex.)表,并附带存储库和服务,那么所有这些都可以避免,这样您就可以更高效地查询数据。

相关问题