JPA如何按集合属性进行分组

时间:2016-08-05 21:19:40

标签: jpa collections group-by

有没有办法按集合属性进行分组?例如,

public class Merchandise {
   id,
   name

}

public class Attribute {
    id,
    name,
    value,

    @ManyToOne
    MerchandiseCost merchandiseCost;
}

public class MerchandiseCost {
    Merchandise merchandise,
    List<Attribute> attributes,
    BigDecimal cost,
}

按商品和属性搜索MerchandiseCost小组。

select merchandise, attributes, sum(cost) from MerchandiseCost group by merchandise, attributes.

这会起作用吗?

编辑: 如果没有,如何使用CriteriaQuery API构建查询以获得如下结果:

Merchandise         Attributes         SUM(COST)
-----------------------------------------------------------
Cloth          size:L, color:RED       10000
Cloth          size:M, color:WHITE     20000
Computer       Memory:4G               80000
Computer       Memory:16G              90000

1 个答案:

答案 0 :(得分:0)

您不能按集合分组,也不能在Select子句中选择多值字段。

Merchandise.class

@Embeddable

public class Merchandise {
private String name;

public Merchandise() {

}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    if (obj.getClass() != getClass()) {
        return false;
    }
    Merchandise rhs = (Merchandise) obj;
    return new EqualsBuilder()
            .append(this.name, rhs.name)
            .isEquals();
}

@Override
public int hashCode() {
    return new HashCodeBuilder()
            .append(name)
            .toHashCode();
}
}

Attribute.class

@Embeddable
public class Attribute {
private int id;
private String name;
private String value;

private MerchandiseCost merchandiseCost;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getValue() {
    return value;
}



public void setValue(String value) {
    this.value = value;
}

@ManyToOne
public MerchandiseCost getMerchandiseCost() {
    return merchandiseCost;
}

public void setMerchandiseCost(MerchandiseCost merchandiseCost) {
    this.merchandiseCost = merchandiseCost;
}


@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    if (obj.getClass() != getClass()) {
        return false;
    }
    Attribute rhs = (Attribute) obj;
    return new EqualsBuilder()
            .append(this.id, rhs.id)
            .append(this.name, rhs.name)
            .append(this.value, rhs.value)
            .append(this.merchandiseCost, rhs.merchandiseCost)
            .isEquals();
}

@Override
public int hashCode() {
    return new HashCodeBuilder()
            .append(id)
            .append(name)
            .append(value)
            .append(merchandiseCost)
            .toHashCode();
}
}

MerchandiseCost.class

@Entity
public class MerchandiseCost extends ABaseEntity {
private Merchandise merchandise;
private List<Attribute> attributes;

private BigDecimal cost;

@Embedded
public Merchandise getMerchandise() {
    return merchandise;
}

public void setMerchandise(Merchandise merchandise) {
    this.merchandise = merchandise;
}

@ElementCollection
@CollectionTable(name = "MERCHANDISE_ATTRIBUTE", joinColumns = @JoinColumn(name = "MERCHANDISE_ID"))
public List<Attribute> getAttributes() {
    return attributes;
}

public void setAttributes(List<Attribute> attributes) {
    this.attributes = attributes;
}

public BigDecimal getCost() {
    return cost;
}

public void setCost(BigDecimal cost) {
    this.cost = cost;
}


@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    if (obj.getClass() != getClass()) {
        return false;
    }
    MerchandiseCost rhs = (MerchandiseCost) obj;
    return new EqualsBuilder()
            .append(this.merchandise, rhs.merchandise)
            .append(this.attributes, rhs.attributes)
            .append(this.cost, rhs.cost)
            .isEquals();
}

@Override
public int hashCode() {
    return new HashCodeBuilder()
            .append(merchandise)
            .append(attributes)
            .append(cost)
            .toHashCode();
}
}

MerchandiseResult.class

public class MerchandiseResult {
private Merchandise merchandise;
private Attribute attribute;
private BigDecimal cost;

public MerchandiseResult() {
}

public MerchandiseResult(Merchandise merchandise, Attribute attribute, BigDecimal cost) {
    this.merchandise = merchandise;
    this.attribute = attribute;
    this.cost = cost;
}

public Merchandise getMerchandise() {
    return merchandise;
}

public void setMerchandise(Merchandise merchandise) {
    this.merchandise = merchandise;
}

public Attribute getAttribute() {
    return attribute;
}

public void setAttribute(Attribute attribute) {
    this.attribute = attribute;
}

public BigDecimal getCost() {
    return cost;
}

public void setCost(BigDecimal cost) {
    this.cost = cost;
}


@Override
public boolean equals(Object obj) {
    if (obj == null) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    if (obj.getClass() != getClass()) {
        return false;
    }
    MerchandiseResult rhs = (MerchandiseResult) obj;
    return new EqualsBuilder()
            .append(this.merchandise, rhs.merchandise)
            .append(this.attribute, rhs.attribute)
            .append(this.cost, rhs.cost)
            .isEquals();
}

@Override
public int hashCode() {
    return new HashCodeBuilder()
            .append(merchandise)
            .append(attribute)
            .append(cost)
            .toHashCode();
}
}

MerchandiseDao.class

@Stateless
public class MerchandiseDao {
@PersistenceContext(name = "tngo")
private EntityManager entityManager;

public void readCost(){
    Query query = entityManager.createQuery("select NEW tngo.cert.training.model.MerchandiseResult(mc.merchandise, att, sum(mc.cost)) from MerchandiseCost mc join mc.attributes att group by mc.merchandise, att");
    query.getResultList();
}
}