Подсчет вхождений идентификатора в таблице "многие ко многим" в Hibernate
Я создаю функцию, где мое приложение будет показывать наиболее понравившиеся фотографии.
У меня есть этот класс
public class User{
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.user", cascade = CascadeType.ALL)
private Set<UserLikedPhoto> likedPhotos = new HashSet<UserLikedPhoto>();
//Other properties and accessor methods.
}
Фото класс
public class Photo{
@OneToMany(fetch = FetchType .LAZY ,mappedBy = "pk.photo")
private Set<UserLikedTrack> likedByUsers = new HashSet<UserLikedTrack>();
//Other properties and accessor methods
}
CompoundId/CompoundObject
@Embeddable
public class UserLikedPhotoId implements Serializable {
@ManyToOne
private UserProfile user;
@ManyToOne
private Photo photo;
//Other Properties and accessor methods.
}
И класс, который содержит CompoundObject и дату
@Entity
@AssociationOverrides({
@AssociationOverride(name = "pk.userId", joinColumns = @JoinColumn(name = "userId")),
@AssociationOverride(name = "pk.photoid", joinColumns = @JoinColumn(name = "photoId")) })
public class UserLikedPhoto{
@EmbeddedId
private UserLikedPhotoId pk = new UserLikedPhotoId();
@Column
@Temporal(TemporalType.DATE)
private Date date;
//Other Entities and accssor methods
}
С этим классом. Я буду сгенерирован с этим типом таблицы
------------------------------
| date | UserId photoId |
-----------------------------
| 2010-12-23 | 1 | 23 |
| 2010-12-21 | 2 | 23 |
| 2010-12-23 | 1 | 24 |
| 2010-12-21 | 5 | 23 |
Теперь я хочу получить фотографию с наибольшим количеством голосов (может быть, топ-5 или топ-10 на определенную дату) в этом примере, фотография с наибольшим количеством голосов - это фотография № 23. А вторая по популярности - номер 24.
Как в Hibernate сделать запрос для такого рода задач?
2 ответа
Без тестирования действительно трудно понять это с самого начала, но вот моя попытка:
Query q = session.createQuery("select p from
Photo as p,
(select ulp.pk.photo.photoId as photoId from UserLikedPhoto ulp
where ulp.date = :someDate group by ulp.pk.photo.photoId
order by count(ulp.pk.photo.photoId) desc) as top
where p.photoId = top.photoId");
q.setParameter("someDate", new Date())
q.setMaxResults(10);
List<Photo> topPhotos = q.list();
Не пытаться это.. но просто попробуйте... если не сработало, я удалю этот ответ
select photoId, count(photoId) from UserLikedPhoto group by photoId order by count(photoid) desc
в этом запросе мы группируем по photoid, поэтому для 1 идентификатора фотографии будет только 1 строка.
подсчет того, сколько раз эта фотография доступна в UserLikedPhoto
скажет нам количество лайков фотографии...
мы заказываем с desc, так что один с наиболее похожим будет на вершине. вы спросили, хотите ли вы первые 5 или 10... так что вы можете использовать топ 10 или топ 5 sql в выражении select
итоговый sql будет примерно таким...
select top 10 photoId, count(photoId) from UserLikedPhoto group by photoId order by count(photoid) desc
Hibernate также позволяет поддерживать нативный sql.