Spring JPQL для массива строк как необязательный параметр - PullRequest
0 голосов
/ 26 июня 2018

Я создал REST API с конечной точкой GET, которая должна возвращать письма, соответствующие заданным критериям. Все параметры конечной точки GET являются необязательными и должны быть объединены AND:

  1. id: идентификатор почты (автоматически генерируется при создании новой почты)
  2. mail_from: отправитель письма
  3. received_before: фильтры для писем, полученных до указанной даты
  4. received_after: фильтры для писем, полученных после указанной даты
  5. rcpt_to: массив адресов электронной почты получателя; важно, чтобы отфильтрованные письма содержали ВСЕХ получателей, заданных как значения параметров rcpt_to

Поскольку я не смог отфильтровать по диапазону дат с помощью создания запроса по именам методов, описанным в Spring Docs , я создал пользовательские запросы.

Я реализовал запрос для параметров 1-4 (см. Метод getMailByCustomQuery) и другой запрос для параметра rcpt_to (см. Метод getMailByRecipient). Поскольку последний использует HAVING, я не могу просто объединить оба запроса. Как я могу объединить оба запроса, чтобы иметь один метод / запрос для моей конечной точки GET? Или есть альтернативный подход?

MailRepository.java

@RepositoryRestResource
public interface MailRepository extends JpaRepository<Mail, Long> {
    @Query("SELECT m FROM Mail m " +
            "WHERE (:id IS NULL OR m.id = :id) " +
            "AND (:mailFrom IS NULL OR m.mailFrom = :mailFrom)" +
            "AND ( CAST(:receivedBefore AS date) IS NULL OR m.received < :receivedBefore) " +
            "AND ( CAST(:receivedAfter AS date) IS NULL OR m.received > :receivedAfter)")
    List<Mail> getMailByCustomQuery(
            @Param("id") Long id,
            @Param("mailFrom") String mailFrom,
            @Param("receivedBefore") Date receivedBefore,
            @Param("receivedAfter") Date receivedAfter
    );

    @Query("SELECT m " +
            "FROM Mail m LEFT JOIN m.rcptTo to2 " +
            "WHERE to2 IN :rcptTo " +
            "GROUP BY m.id " +
            "HAVING COUNT(DISTINCT to2) = :rcptToLength")
    List<Mail> getMailByRecipient(
            @Param("rcptTo") List<String> rcptTo,
            @Param("rcptToLength") Long rcptToLength
    );
}

MailRestController.java

@RestController
@RequestMapping("/mailStore")
public class MailRestController {
private MailRepository repository;
@Inject
public void setRepository(MailRepository repository) {
    this.repository = repository;
}

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addMail(@RequestBody Mail mail) {
    return new ResponseEntity<>(repository.save(mail), HttpStatus.CREATED);
}

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Mail>> getMail(
        @RequestParam(required = false) Long id,
        // Example for timestamp format: 2001-07-22T12:08:56.235-07:00
        @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date received_before,
        @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date received_after,
        @RequestParam(required = false) String mail_from) {
    return new ResponseEntity<>(repository.getMailByCustomQuery(id, mail_from, received_before, received_after), HttpStatus.OK);
}

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Mail>> getMail(
        @RequestParam(required = false) List<String> rcpt_to) {
    return new ResponseEntity<>(repository.getMailByRecipient(rcpt_to, (long) rcpt_to.size()), HttpStatus.OK);
}

}

Mail.java (метод получения и установки не указан)

@Entity
@EnableAutoConfiguration
public class Mail {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @JsonProperty("id")
    private Long id;

    @Column(name = "received")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
    @Temporal(TemporalType.TIMESTAMP)
    @JsonProperty("received")
    private Date received;

    @JsonProperty("received_from")
    private String receivedFrom;

    @JsonProperty("received_by")
    private String receivedBy;

    @JsonProperty("mail_from")
    private String mailFrom;

    @JsonProperty("data")
    private String data;

    @ElementCollection(fetch = FetchType.EAGER, targetClass = String.class)
    @CollectionTable(name = "rcptTo")
    @Column(name = "Value")
    @JsonProperty("rcpt_to")
    private List<String> rcptTo = new ArrayList<>();

public Mail(Date received, String receivedFrom, String receivedBy, String mailFrom,
            List<String> rcptTo, String data) {
    this.received = received;
    this.receivedFrom = receivedFrom;
    this.receivedBy = receivedBy;
    this.mailFrom = mailFrom;
    this.rcptTo = rcptTo;
    this.data = data;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...