如何替换JPA等价物上的原生order by子句?
我使用JPA2.0标准生成器。我需要从一个表中获取数据,并按列对另一个表中的数据进行排序。此表与一个域有关系:如何替换JPA等价物上的原生order by子句?,jpa,subquery,one-to-many,Jpa,Subquery,One To Many,我使用JPA2.0标准生成器。我需要从一个表中获取数据,并按列对另一个表中的数据进行排序。此表与一个域有关系: class Club{ @OneToMany(mappedBy = "club") private List<Address> addresses; ... } class Address{ @JoinColumn(name = "club_id", referencedColumnName = "id") @ManyToOne(fetch
class Club{
@OneToMany(mappedBy = "club")
private List<Address> addresses;
...
}
class Address{
@JoinColumn(name = "club_id", referencedColumnName = "id")
@ManyToOne(fetch = FetchType.LAZY)
private Club club;
@Column(name = "type")
private Long type;
@Column(name = "full_address")
private String full_address;
...
}
我如何替换JPA等价物上的原生order by子句
谢谢 它不是非常优雅,但它完成了任务
使您的“俱乐部”类实现可比性。按逻辑将顺序放入可比项中。然后使用Collections.sort(unsortedList)将列表转换为已排序的形式。还有一个Collections.sort(unsortedList,Comparable)方法可能很有用,特别是当您正在执行一系列类似的方法时,这些方法只是根据顺序而变化。此本机查询也解决了这个问题,可以用JPA查询代替
select c.full_name, min(a.full_address) FROM club c LEFT JOIN address a on c.id = a.club_id
where a.id is null or a.type=1 or not exists(SELECT 1 from address aSub WHERE aSub .club_id=c.id AND aSub.type=1)
GROUP BY c.id, c.full_name ORDER BY min(a.full_address);
相当于JPA的金额
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<ClubItem> query = builder.createQuery(ClubItem.class);
Root<Club> root = query.from(Club.class);
Join<Club, Address> addressJoin = root.join(Club_.address, JoinType.LEFT);
query.select(builder.construct(ClubItem.class, root.get(Club_.id), root.get(Club_.fullName), builder.function("min", String.class, addressJoin.get(Address_.fullAddress))));
Subquery<Address> subquery = query.subquery(Address.class);
Root<Address> addressRoot = subquery.from(Address.class);
subquery.select(addressRoot);
subquery.where(
builder.and(
builder.equal(addressRoot.get(Address_.type), 1),
builder.equal(addressRoot.get(Address_.clubId), root.get(Club_.id))));
query.where(builder.or(builder.isNull(addressJoin), builder.equal(addressJoin.get(Address_.type), builder.literal(new Long(1))),
builder.not(builder.exists(subquery))));
query.groupBy(root.get(Club_.id), root.get(Club_.fullName))
Order order = builder.asc(builder.function("min", String.class, addressJoin.get(Address_.fullAddress)));
query.orderBy(order);
TypedQuery<ClubItem> contentQuery = em.createQuery(query);
CriteriaBuilder=em.getCriteriaBuilder();
CriteriaQuery=builder.createQuery(ClubItem.class);
Root=query.from(Club.class);
Join addressJoin=root.Join(俱乐部地址,JoinType.LEFT);
query.select(builder.construct(ClubItem.class,root.get(Club.id),root.get(Club.fullName),builder.function(“min”,String.class,addressJoin.get(Address.fullAddress)));
Subquery Subquery=query.Subquery(Address.class);
根地址Root=subquery.from(Address.class);
子查询。选择(addressRoot);
subquery.where(
建筑商和(
builder.equal(addressRoot.get(Address.type),1),
builder.equal(addressRoot.get(Address.clubId),root.get(Club.id));
query.where(builder.or(builder.isNull(addressJoin)、builder.equal(addressJoin.get(Address.type)、builder.literal(new Long(1)),
builder.not(builder.exists(子查询));
groupBy(root.get(Club.id),root.get(Club.fullName))
Order Order=builder.asc(builder.function(“min”,String.class,addressJoin.get(Address\uu.fullAddress)));
query.orderBy(订单);
TypedQuery contentQuery=em.createQuery(查询);
俱乐部是否有可能拥有多个地址,并以不确定的顺序排列?否则,您的JPA提供者可能允许您像使用表一样使用from子句中的子查询。但是,如果您修改查询以提供您想要的内容,可能会更好——可能是按地址排序的不同全名。类似于“从俱乐部c选择c.full_名称加入c.addresses a,其中a.type=1按a.full_地址订购”的内容谢谢您的回答。一个俱乐部可以由多个类型为1的地址组成,因此当使用join
时,会出现俱乐部的副本。我需要获取所有俱乐部(如果存在类型为1或否的地址)并对其进行排序。添加一个不同的关键字,但如果类型1不是唯一的,我也不太明白如何使用子查询对非唯一地址进行排序。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<ClubItem> query = builder.createQuery(ClubItem.class);
Root<Club> root = query.from(Club.class);
Join<Club, Address> addressJoin = root.join(Club_.address, JoinType.LEFT);
query.select(builder.construct(ClubItem.class, root.get(Club_.id), root.get(Club_.fullName), builder.function("min", String.class, addressJoin.get(Address_.fullAddress))));
Subquery<Address> subquery = query.subquery(Address.class);
Root<Address> addressRoot = subquery.from(Address.class);
subquery.select(addressRoot);
subquery.where(
builder.and(
builder.equal(addressRoot.get(Address_.type), 1),
builder.equal(addressRoot.get(Address_.clubId), root.get(Club_.id))));
query.where(builder.or(builder.isNull(addressJoin), builder.equal(addressJoin.get(Address_.type), builder.literal(new Long(1))),
builder.not(builder.exists(subquery))));
query.groupBy(root.get(Club_.id), root.get(Club_.fullName))
Order order = builder.asc(builder.function("min", String.class, addressJoin.get(Address_.fullAddress)));
query.orderBy(order);
TypedQuery<ClubItem> contentQuery = em.createQuery(query);