Подсчет вхождений идентификатора в таблице "многие ко многим" в 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.

Другие вопросы по тегам