Построение CriteriaQuery из сложного SQL запроса - PullRequest
0 голосов
/ 16 января 2020

Я новичок в Criteria API и пытаюсь создать CriteriaQuery из этого простого SQL:

SELECT * 
FROM user_acc u 
WHERE (SELECT count(b) FROM bonus b WHERE b.employee_id = u.id) > 8;

Может кто-нибудь помочь мне с этим? Я в замешательстве ...

Ответы [ 2 ]

0 голосов
/ 17 января 2020

Вам нужны объекты, чтобы использовать Criteria API

@Entity
@Table(name = "user_acc")
public class UserAcc{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    // getters setters
}

@Entity
@Table(name = "employee")
public class Employee{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    // getters setters
}

@Entity
@Table(name = "bonus")
public class Bonus{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "employee_id")
    Employee employee;

    // getters setters
}

, тогда вы можете использовать это

public List<UserAcc> getUserAccs(EntityManager em) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<UserAcc> query = builder.createQuery(UserAcc.class);
        Root<UserAcc> user = query.from(UserAcc.class);

        Subquery<Bonus> subquery = query.subquery(Bonus.class);
        Root<Bonus> bonus = subquery.from(Bonus.class);
        Path<Long> employeeId = bonus.get("employee").get("id");

        Predicate subqueryPredicate = builder.equal(user.get("id"), employeeId);            
        Expression<Long> bonusCount = builder.count(bonus);

        subquery.select(bonusCount)
                .where(subqueryPredicate)
                .groupBy(employeeId)
                .having(builder.greaterThan(bonusCount, 8L);

        Predicate predicate = builder.exists(subquery);
        query.select(user).where(predicate);

        return em.createQuery(query).getResultList();
} 

Окончательный запрос немного отличается, но результат должен быть ожидаемым.

Я написал этот код в текстовом редакторе, поэтому его нужно протестировать.

0 голосов
/ 16 января 2020

Вы можете перечислить все нужные неагрегированные столбцы в списке SELECT и GROUP BY, содержащем предложение HAVING:

SELECT b.br, b.employee_id 
  FROM user_acc u 
  JOIN bonus b ON b.employee_id = u.id
 GROUP BY b.br, b.employee_id 
HAVING count(b.br) > 8;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...