我创建了一个具有端点GET
的REST API,该端点应返回与给定条件匹配的邮件。 GET
端点的所有参数都是可选的,应由AND
串联:
id
:邮件的ID(在创建新邮件时自动生成)mail_from
:邮件的发件人received_before
:过滤给定日期之前收到的邮件received_after
:过滤给定日期之后收到的邮件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 (省略了getter和setter)
@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;
}