当前位置: 首页 > 知识库问答 >
问题:

Spring boot JPA如何在多个关系中给定一个对象来查询@OneToMany关系

邵轶
2023-03-14

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

@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()
}

我希望能够获取特定工人的工作列表

我尝试了一些本地和非本地的查询,但现在只尝试使用命名方法,老实说,我想在这里任何有效的方法都应该适用于我的工作回购

@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

在一个工人的输入中。我也尝试查询工人的UUID,因为那是连接表中的内容

JPA创建一个带有两个外键的连接表

jobs_requests

和列

job_id UUID
requests_id UUID

共有2个答案

黄逸清
2023-03-14

还值得注意的是,对于所有实际用途,您应该尽量避免显式的ManyTo多国注释。您应该创建一个新的实体/表,其中包含作业和工人的字段,并与各自的实体建立ManyToOne关联。

为什么要避免显式的ManyToMore是因为,例如,当有一个特定的工作时,例如JavaDev,并且给定的工作有1000个工人。有一次你有一个JavaDev实体,你想得到所有年龄在20到25岁之间的工人。为此,需要迭代作为JavaDev实体一部分的工人列表并将其过滤掉。当发生这种情况时,有两种情况:

  1. Workers list是一个延迟关联,当您尝试访问它时,hibernate将向数据库发送1000个(n 1个问题)查询
  2. Workers list是一个急切的关联,hibernate将向数据库发送相同数量的查询,但只要您尝试获取JavaDev实体

因此,执行时间会增加,因为数据库本身会有不必要的负载。在更大的项目中,这将变得更加复杂。

如果您创建自己的manytomany(job_workers for ex.)表,并附带存储库和服务,那么所有这些都可以避免,从中您可以更高效地查询数据。

东方骏
2023-03-14

你提到一个作业可以有很多工人,你也提到你想为一个特定的工人得到一个工作列表。所以这听起来像是一个ManyTo多国关系,而不是一个多对多。

对于ManyTo多国关系,连接表是不可避免的。您需要在两个实体上指定@ManyTo多国注释,然后您可以使用WorkerRepository查询该工作人员,然后通过worker.getJobs()获取该工作人员的作业列表。

以下是多人关系的设置,希望能有所帮助:

java prettyprint-override">@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()
)
 类似资料:
  • 我需要在我的数据库中创建多个多对多的关系。 有一个“主”表,我们称之为“项目”。 然后有3个表包含“选项”。 假设我们有:品类、地域、用户。这些保存的唯一信息是项目的名称和ID。 可以将多个类别、区域和用户分配给多个项目。 因此,我有两个选项来创建这种关系: 1)为每个'选项'表创建关系表。每个表包含两列:project_id和category_id、region_id或user_id。使用这种方

  • 实现了一对多的关系,它运行良好。 我的问题是当我运行下面的查询时,如果表有100个员工行,每个员工有两个部门。数据库查询被调用了101次,因为对每个员工都是调用部门查询,要完成调用全部100行需要很长时间,有没有人可以提出替代的解决方案? 输出XML:

  • 我正在使用Ebean和Play 2框架,并得到两个模型:用户模型和图书模型。用户模型与图书模型以一对多关系连接。所以每个用户可以有很多书或者根本没有书。图书模式本身也有其特性。现在我想在用户模型中创建一个查询,它只返回用户,这些用户拥有具有某些属性的书籍。例如:一个属性可能是条件,如新建或使用。现在给我所有有新条件的书的用户。是否可以使用Ebean方法创建这样的查询?还是我必须使用原始SQL?

  • 问题内容: 我有两个表A和Band,A与B之间的关系是A —>一对多—> B 通常,对于A的每条记录,我都有一个B的记录。 我正在尝试编写一个查询,该查询将为我提供A的 唯一 记录列表,其中B中的 记录 超过 一个(多个) 。 我很困惑,因为我只完成了基本的sql查询,而这对我来说似乎很复杂。 可以请一个人指导我正确答案或给我解决方案。 编辑: 好吧,我尝试了下面的事情,它给了我一个错误 从A a

  • 我有一个桌子实验和一个桌子标签。一个实验可能有许多标签。架构: 是否可以使用返回实验和相应标签列表的jooq创建查询? 类似

  • 我试图让api返回一个注释列表,通过与标签的多对多关系关联,给定一个标签ID。Spring boot自动创建了一个名为notes_tables的桥接表,其中包含一个notes_id字段和一个labels_id字段。Spring Boot还创建了一个notes表和一个labels表。我尝试了以下步骤: 我只需要让它工作,但我特别好奇我是否能让它与jpa方法查询一起工作。任何查询都可以,只要它可以工作