2

我有一个 JPA 数据库设置,如下所示:

@Entity
public class Contact {

    @Id
    private Long id;
    @Column(length = 64)
    private String firstname;
    @Column(length = 64)
    private String surname;

    @OneToMany(mappedBy = "contact") 
    private List<Address> adresses = new ArrayList<Address>();
    @OneToMany(mappedBy = "contact") 
    private List<Telephone> telephones = new ArrayList<Telephone>();

}

@Entity
public class Address {

    @Id
    private Long id;
    @Column(length = 128)
    private String street;
    @Column(length = 16)
    private String plz;


    @ManyToOne 
    private Contact contact;

}

@Entity
public class Telephone {

    @Id
    private Long id;
    @Column(length = 32)
    private String number;


    @ManyToOne
    private Contact contact;

}

现在我的搜索表单有以下查询:

em.createQuery("SELECT DISTINCT c FROM Contact c LEFT JOIN c.addresses a LEFT JOIN c.telephones t "
                        + "WHERE c.surnameLIKE '%"+var_surname+"%' "
                        + "AND c.firstname LIKE '%"+var_firstname+"%' "
                        + "AND a.street LIKE '%"+var_street+"%'"
                        + "AND t.nummer LIKE '%"+var_telephone+"%'"
                        ).getResultList();

我现在的问题是如何在一个 JPA 查询中加入所有 3 个表以查找名字、街道和号码?我已经尝试过使用 LEFT JOIN,但是当例如 Telephone 表为空时(如果所有表都有适当的条目,它可以正常工作),我没有得到任何结果。即使没有电话号码,我也希望有一个包含联系人的结果列表,即使联系人有多个电话号码,也只有一个结果。

非常感谢您提前提供的帮助。

4

4 回答 4

0

您是否尝试过使用“LEFT OUTER JOIN”,例如下面?

           "SELECT DISTINCT c FROM Contact c LEFT OUTER JOIN c.addresses a LEFT OUTER JOIN c.telephones t "
          + "WHERE c.surnameLIKE '%"+var_surname+"%' "
          + "AND c.firstname LIKE '%"+var_firstname+"%' "
          + "AND a.street LIKE '%"+var_street+"%'"
          + "AND t.nummer LIKE '%"+var_telephone+"%'"
          ).getResultList();
于 2012-09-28T19:01:04.313 回答
0

DISTINCT 应​​该删除重复项,

如果没有关系,您需要使用 OR 来获得结果,

      + "AND ((a.id is null) OR (a.street LIKE '%"+var_street+"%'))"
于 2012-10-01T13:24:24.070 回答
0

感谢您提供有用的答案。最后,我必须通过动态构建搜索字符串来解决问题,根据用户留空的字段有选择地添加/删除连接操作数的某些部分。

    public List<Person> querySearch(String snachname, String svorname, String srechtsform, String sadresse, String sort, String sland, String stelefon, String semail, LoadGroup group) {
        if(srechtsform.equals("Alle")) {
            srechtsform = "";
        }
        if(sland.equals("Alle")) {
            sland = "";
        }
        String q = "SELECT DISTINCT * FROM Person p LEFT OUTER JOIN Adresse a ON (a.PERSON_ID=p.ID) LEFT OUTER JOIN Telefon t ON (t.PERSON_ID=p.ID) LEFT OUTER JOIN Email e ON (e.PERSON_ID=p.ID) WHERE p.nachname1 LIKE '%"+snachname+"%'AND p.vorname LIKE '%"+svorname+"%' AND p.rechtsform LIKE '%"+srechtsform+"%' ";
        if(sadresse.equals("") && sort.equals("") && sland.equals("")) {
            q += "AND (a.ID IS NULL OR (a.strasse LIKE '%"+sadresse+"%' AND a.ort LIKE '%"+sort+"%' AND a.land LIKE '%"+sland+"%')) "; 
        } else {
            q += "AND a.strasse LIKE '%"+sadresse+"%' AND a.ort LIKE '%"+sort+"%' AND a.land LIKE '%"+sland+"%' "; 
        }
        if(stelefon.equals("")) {
            q += "AND (t.ID IS NULL OR t.nummer LIKE '%"+stelefon+"%') ";
        } else {
            q += "AND t.nummer LIKE '%"+stelefon+"%' ";
        }
        if(semail.equals("")) {
            q += "AND (e.ID IS NULL OR e.mailadresse LIKE '%"+semail+"%') ";
        } else {
            q += "AND e.mailadresse LIKE '%"+semail+"%' ";
        }
        q += "GROUP BY p.ID";
        Query query = em.createNativeQuery(q, Person.class);
        if(group!=null) { query.setHint(QueryHints.LOAD_GROUP, group); }
        return query.getResultList();
    }
于 2012-10-24T08:08:13.310 回答
0

JPA 不支持“LEFT OUTER JOIN a ON b”样式语法(请参阅http://chrisiecorner.blogspot.fi/2012/12/jpa-and-outer-joins.html

您必须进行本机查询。

于 2014-02-06T04:39:36.220 回答