Спецификация JPA для выбора уникальных строк на основе одного отдельного столбца - PullRequest
0 голосов
/ 27 апреля 2020

Я хочу выбрать строки с отдельным адресом электронной почты, см. Пример таблицы ниже:

+----+---------+-------------------+-------------+
| id | title   | email             | commentname |
+----+---------+-------------------+-------------+
|  3 | test    | rob@hotmail.com   | rob         |
|  4 | i agree | rob@hotmail.com   | rob         |
|  5 | its ok  | rob@hotmail.com   | rob         |
|  6 | hey     | rob@hotmail.com   | rob         |
|  7 | nice!   | simon@hotmail.com | simon       |
|  8 | yeah    | john@hotmail.com  | john        |
+----+---------+-------------------+-------------+

Желаемый результат будет:

+----+-------+-------------------+-------------+
| id | title | email             | commentname |
+----+-------+-------------------+-------------+
|  3 | test  | rob@hotmail.com   | rob         |
|  7 | nice! | simon@hotmail.com | simon       |
|  8 | yeah  | john@hotmail.com  | john        |
+----+-------+-------------------+-------------+

Где мне все равно какое значение столбца id возвращается. Какая спецификация JPA может использоваться для этого?

Вот класс спецификации,

public class UserSearchSpecification implements Specification<UserSearch> {

    private static final Logger LOGGER = LogManager.getLogger(UserSearchSpecification.class);

    private static final long serialVersionUID = 1L;
    private List<SearchCriteria> list;

    /**
     * Custom JPA Specification Constructor
     * 
     */
    public UserSearchSpecification() {
        this.list = new ArrayList<>();
    }

    public void add(SearchCriteria criteria) {
        list.add(criteria);
    }

    @Override
    public Predicate toPredicate(Root<UserSearch> root, CriteriaQuery<?> arg1, CriteriaBuilder builder) {
         //create a new predicate list
        List<Predicate> predicates = new ArrayList<>();

        //add add criteria to predicates
        for (SearchCriteria criteria : list) {
            if (criteria.getOperation() == (SearchOperation.GREATER_THAN)) {
                predicates.add(builder.greaterThan(
                        root.get(criteria.getKey()), criteria.getValue().toString()));
            } else if (criteria.getOperation() == (SearchOperation.LESS_THAN)) {
                predicates.add(builder.lessThan(
                        root.get(criteria.getKey()), criteria.getValue().toString()));
            } else if (criteria.getOperation() == (SearchOperation.GREATER_THAN_EQUAL)) {
                predicates.add(builder.greaterThanOrEqualTo(
                        root.get(criteria.getKey()), criteria.getValue().toString()));
            } 
        }

        return builder.and(predicates.toArray(new Predicate[0]));
    }

}

1 Ответ

0 голосов
/ 27 апреля 2020

Я очень ненавижу API критериев JPAs для создания реального кода, но основная идея c заключается в том, что вы создаете следующую конструкцию:

from MyEntity e 
where e.id in (
    select min(id) 
    from MyEntity e2 
    where e.email = e2.email
)

Это должно быть выражено с помощью API Criteria и, следовательно, Спецификации Spring Data JPA.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...