代码之家  ›  专栏  ›  技术社区  ›  Nemeth Attila

如何编写多对多关联表的查询

  •  1
  • Nemeth Attila  · 技术社区  · 6 年前

    我有两个实体,它们之间有多对多的关系。我想在关联表上写一个查询。

    Here are the two entities. Craftsmen and Skill.
    I want to write a query which selects all Craftsmen with a given skill. 
    
        @Entity
        @Table(name = "craftsman")
        public class Craftsman {
    
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            private Long id;
    
            @ManyToMany
            @JoinTable(name = "craftman_skill", joinColumns = @JoinColumn(name = "craftman_id", referencedColumnName = "id"), 
                inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName = "id"))
            private List<Skill> skillList;
        }
            @Entity
            @Table(name = "skill")
            public class Skill {
                @ManyToMany(mappedBy = "skillList")
                @JsonBackReference
                private List<Craftsman> craftmanList;
            }
    

    以下是我尝试过的:

    @Query("SELECT c FROM Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId")
        public List<Craftsman> getCraftsmanBySkill(@Param("skillId") Long skillId);
    

    以下是MySql中的查询: 这将获得所有具有id 1技能的工匠:

    select c.name from craftsman c, craftman_skill cs 
    where cs.craftman_id = c.id 
    and cs.skill_id = 1;
    

    以下是我得到的错误:

    Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: skill_id of: com.craftsmen.crafts.persistence.Skill [SELECT c FROM com.craftsmen.crafts.persistence.Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId ]
    Caused by: org.hibernate.QueryException: could not resolve property: skill_id of: com.craftsmen.crafts.persistence.Skill [SELECT c FROM com.craftsmen.crafts.persistence.Craftsman c JOIN c.skillList sl WHERE c.skillList.skill_id = :skillId ]
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Christian Riese    6 年前

    我想问题是,你的 Skill 实体确实没有skill\u id或更好的 id

    你有没有试过 技巧 实体an 身份证件

    @Entity
    @Table(name = "skill")
    public class Skill {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)
       private Long id;
    
       @ManyToMany(mappedBy = "skillList")
       @JsonBackReference
       private List<Craftsman> craftmanList;
    }
    

    在您的 Craftsman 实体

    @Entity
    @Table(name = "craftsman")
    public class Craftsman {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @ManyToMany
        @JoinTable(name = "craftman_skill", joinColumns = @JoinColumn(name = "craftman_id", referencedColumnName = "id"), 
            inverseJoinColumns = @JoinColumn(name = "skill_id", referencedColumnName = "id"))
        private List<Skill> skillList;
    }
    

    然后更改 Query

    SELECT c FROM Craftsman c JOIN c.skillList sl WHERE sl.id = :skillId
    

    这应该可以奏效。

        2
  •  0
  •   marc_s HarisH Sharma    6 年前

    您还可以考虑在此处使用JpaRepository:

    public interface CraftsmanRepository extends JpaRepository<Craftsman, String> {
        public List<Craftsman> getBySkillListIn(@NotEmpty List<Skill> skillList);
    

    }

    这意味着,Jpa通过写入方法名称已经将查询映射到您的SQL查询(如果没有映射,请尝试)

    在方法的末尾,“In”表示它应该检查多个值,而不是一个值

    在SQL中 In 还可以执行以下操作:

    where <condition> And <>condition And <condition> And...