jpql根据另一个表中的某些属性从表中选择对象?

时间:2014-10-31 09:45:52

标签: java mysql jsf jpa jpql

我是jpql的新手。 我有两个mySql表。 表格广告:包含列:

  

id,姓名,描述,电话,类别等。

并使用以下列表ads_property:

id          int 11
advert_id   int 11  
name        varchar 255 
value       varchar 255     
descr       varchar 255

我的目标是从表advert中选择对象,该对象具有在表category = "flats"中编写的属性advert,其名称number_rooms = "234"写在表advert_property中。

我对jpql syntaxis有点困惑,我来到这个解决方案:

 Query q = em.createQuery("SELECT ap FROM AdvertProperty as ap, Advert as a "  
 + " where a.category= 'flats' and ap.advertId = a.id and ap.name='number_rooms' ");

List<Advert> ads = q.getResultList();

但它并不像我需要的那样工作..

请建议, 感谢

广告实体:

public class Advert implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
private Integer id;
@Size(max = 255)
private String title;
@Lob
@Size(max = 65535)
private String content;
private Integer price;
@Size(max = 255)
@Column(name = "contact_person")
private String contactPerson;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Size(max = 255)
private String email;
// @Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$", message="Invalid phone/fax format, should be as xxx-xxx-xxxx")//if the field contains phone or fax number consider using this annotation to enforce field validation
@Size(max = 255)
private String phone;
@Column(name = "address_id")
private Integer addressId;
@Column(name = "category_id")
private Integer categoryId;
@Basic(optional = false)
@NotNull
@Column(name = "company_type")
private boolean companyType;
@Basic(optional = false)
@NotNull
private boolean approved;
@Column(name = "user_id")
private Integer userId;
@Column(name = "who_can_watch")
private Integer whoCanWatch;
@Basic(optional = false)
@NotNull
@Column(name = "creation_date")
@Temporal(TemporalType.TIMESTAMP)
private Date creationDate;
@Size(max = 255)
private String razdel;

public Advert() {
}

public Advert(Integer id) {
    this.id = id;
}

AdvertProperty实体:

   @Entity
@Table(name = "advert_property")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "AdvertProperty.findAll", query = "SELECT a FROM AdvertProperty a"),
    @NamedQuery(name = "AdvertProperty.findById", query = "SELECT a FROM AdvertProperty a WHERE a.id = :id"),
    @NamedQuery(name = "AdvertProperty.findByAdvertId", query = "SELECT a FROM AdvertProperty a WHERE a.advertId = :advertId"),
    @NamedQuery(name = "AdvertProperty.findByName", query = "SELECT a FROM AdvertProperty a WHERE a.name = :name"),
    @NamedQuery(name = "AdvertProperty.findByValue", query = "SELECT a FROM AdvertProperty a WHERE a.value = :value"),
    @NamedQuery(name = "AdvertProperty.findByDescr", query = "SELECT a FROM AdvertProperty a WHERE a.descr = :descr")})
public class AdvertProperty implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    private Integer id;
    @Column(name = "advert_id")
    private Integer advertId;
    @Size(max = 255)
    private String name;
    @Size(max = 255)
    private String value;
    @Size(max = 255)
    private String descr;

2 个答案:

答案 0 :(得分:0)

修改

由于您已拥有从advert_propertyadvert的外键,因此您可以相应地为您的实体建模

广告实体

...
@OneToOne(mappedBy = "advert")
private AdvertProperty property;
// or this, in case it is one to many
@OneToMany(mappedBy = "advert")
private List<AdvertProperty> properties;
...

AdvertProperty 实体

@ManyToOne // or @OneToOne
@JoinColumn("advert_id")
private Advert advert;

如果是@OneToMany,查询将如下所示

Query q = em.createQuery("SELECT a FROM Advert a join a.properties p where a.category = 'flats' and p.name='number_rooms' ");

如果是@OneToOne,查询将如下所示

Query q = em.createQuery("SELECT a FROM Advert a where a.category = 'flats' and a.property.name='number_rooms' ");

答案 1 :(得分:0)

取决于您实施实体的方式:

SELECT a FROM Advert a JOIN a.properties ap where a.category = 'flats' and ap.name='number_rooms'

SELECT a FROM AdvertPropery ap JOIN ap.advert where a.category = 'flats' and ap.name='number_rooms'

但是,请发布您的实体以获得确切答案。


这不是JPA应该如何进行映射,你应该使用关系注释(@OneToMany,@ ManyToOne,...)和映射注释(@JoinColumn,@ JoinTable,...)

没有关系(和索引!!)你可以做的唯一查询类似于你刚才所做的:

SELECT DISTINCT ap FROM AdvertProperty ap, Advert a where a.category= 'flats' and ap.advertId = a.id and ap.name='number_rooms'

然而,这个查询没有得到优化(没有索引......)并且性能非常糟糕。