'select count(*) from' 在 spring jpa native query 使用分页时被 'select count(where)' 替换
'select count(*) from' is replaced by 'select count(where)' in spring jpa native query when using pagination
我在 @Query 注释内的 JPA 存储库中使用本机查询
@Query(value = " select * from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0), a.maxId, b.maxId) maxId from (select from_number, to_number, " +
" max(id) maxId,direction,type from message where direction='INCOMING' group by from_number, to_number having sum(type= :type)) as a " +
" left join ( select from_number, to_number, max(id) maxId, direction, type from message where direction = 'OUTGOING' and schedule_id is null " +
" group by from_number, to_number) as b on a.from_number=b.to_number and a.to_number=b.from_number) order by generated_time desc ", nativeQuery = true)
Page<Message> getLatestMessageFromThread(@Param("type") String type, Pageable page);
问题是当我执行这个查询时出现语法错误。当我检查日志时,它显示查询中对总消息进行计数的查询如下所示
select count(where) from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0),
a.maxId, b.maxId) maxId from (select from_number, to_number, max(id) maxId,direction,type from
message where direction='INCOMING' group by from_number, to_number having sum(type= 'REVIEW'))
as a left join ( select from_number, to_number, max(id) maxId, direction, type from message
where direction = 'OUTGOING' and schedule_id is null group by from_number, to_number) as b
on a.from_number=b.to_number and a.to_number=b.from_number)
count(*) 替换为count(where)
消息 table 的实体 class 在这里。
@Entity
@Table(name = "message")
public class Message implements Comparable<Message> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "to_number")
private String toNumber;
@Column(name = "from_number")
private String fromNumber;
@Column(name = "message")
private String message;
@Enumerated(EnumType.STRING)
@Column(name = "direction")
private MessageDirection direction;
@Enumerated(EnumType.STRING)
@Column(name = "status")
private MessageStatus status;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private KeywordType type;
@Column(name = "keyword_matched")
private String keywordMatched;
@Column(name = "generated_time")
private Timestamp generatedTime;
@Column(name = "scheduled_time")
private Timestamp scheduledTime;
@Column(name = "details")
private String details;
@Enumerated(EnumType.STRING)
@Column(name = "read_status")
private MessageReadStatus readStatus;
@Column(name = "delivery_code")
private String deliveryCode;
@Column(name = "delivery_description")
private String deliveryDescription;
@Column(name = "data", columnDefinition = "json")
private String messageData;
@ManyToOne
@JoinColumn(name = "schedule_id")
private Schedule schedule;
public Message() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getToNumber() {
return toNumber;
}
public void setToNumber(String toNumber) {
this.toNumber = toNumber;
}
public String getFromNumber() {
return fromNumber;
}
public void setFromNumber(String fromNumber) {
this.fromNumber = fromNumber;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MessageDirection getDirection() {
return direction;
}
public void setDirection(MessageDirection direction) {
this.direction = direction;
}
public MessageStatus getStatus() {
return status;
}
public void setStatus(MessageStatus status) {
this.status = status;
}
public KeywordType getType() {
return type;
}
public void setType(KeywordType type) {
this.type = type;
}
public Timestamp getGeneratedTime() {
return generatedTime;
}
public void setGeneratedTime(Timestamp generatedTime) {
this.generatedTime = generatedTime;
}
public Timestamp getScheduledTime() {
return scheduledTime;
}
public void setScheduledTime(Timestamp scheduledTime) {
this.scheduledTime = scheduledTime;
}
public Schedule getSchedule() {
return schedule;
}
public void setSchedule(Schedule schedule) {
this.schedule = schedule;
}
public String getKeywordMatched() {
return keywordMatched;
}
public void setKeywordMatched(String keywordMatched) {
this.keywordMatched = keywordMatched;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public MessageReadStatus getReadStatus() {
return readStatus;
}
public void setReadStatus(MessageReadStatus readStatus) {
this.readStatus = readStatus;
}
public String getDeliveryCode() {
return deliveryCode;
}
public void setDeliveryCode(String deliveryCode) {
this.deliveryCode = deliveryCode;
}
public String getMessageData() {
return messageData;
}
public void setMessageData(String messageData) {
this.messageData = messageData;
}
public String getDeliveryDescription() {
return deliveryDescription;
}
public void setDeliveryDescription(String deliveryDescription) {
this.deliveryDescription = deliveryDescription;
}
}
为什么要更换它。我怎样才能以正确的方式编写查询?
解决方法是使用countQuery
注解参数:
public interface Repository extends JpaRepository<Entity, Long> {
String QUERY = "FROM entity " +
" WHERE name ILIKE :name ";
@Query(
value = "SELECT * " + QUERY,
countQuery = "SELECT count(*) " + QUERY,
nativeQuery = true
)
Page<KDeploymentView> findBy(
@Param("name") String name,
Pageable p
);
我在 @Query 注释内的 JPA 存储库中使用本机查询
@Query(value = " select * from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0), a.maxId, b.maxId) maxId from (select from_number, to_number, " +
" max(id) maxId,direction,type from message where direction='INCOMING' group by from_number, to_number having sum(type= :type)) as a " +
" left join ( select from_number, to_number, max(id) maxId, direction, type from message where direction = 'OUTGOING' and schedule_id is null " +
" group by from_number, to_number) as b on a.from_number=b.to_number and a.to_number=b.from_number) order by generated_time desc ", nativeQuery = true)
Page<Message> getLatestMessageFromThread(@Param("type") String type, Pageable page);
问题是当我执行这个查询时出现语法错误。当我检查日志时,它显示查询中对总消息进行计数的查询如下所示
select count(where) from message where id in(select if(coalesce(a.maxId,0)>coalesce(b.maxId,0),
a.maxId, b.maxId) maxId from (select from_number, to_number, max(id) maxId,direction,type from
message where direction='INCOMING' group by from_number, to_number having sum(type= 'REVIEW'))
as a left join ( select from_number, to_number, max(id) maxId, direction, type from message
where direction = 'OUTGOING' and schedule_id is null group by from_number, to_number) as b
on a.from_number=b.to_number and a.to_number=b.from_number)
count(*) 替换为count(where) 消息 table 的实体 class 在这里。
@Entity
@Table(name = "message")
public class Message implements Comparable<Message> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "to_number")
private String toNumber;
@Column(name = "from_number")
private String fromNumber;
@Column(name = "message")
private String message;
@Enumerated(EnumType.STRING)
@Column(name = "direction")
private MessageDirection direction;
@Enumerated(EnumType.STRING)
@Column(name = "status")
private MessageStatus status;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private KeywordType type;
@Column(name = "keyword_matched")
private String keywordMatched;
@Column(name = "generated_time")
private Timestamp generatedTime;
@Column(name = "scheduled_time")
private Timestamp scheduledTime;
@Column(name = "details")
private String details;
@Enumerated(EnumType.STRING)
@Column(name = "read_status")
private MessageReadStatus readStatus;
@Column(name = "delivery_code")
private String deliveryCode;
@Column(name = "delivery_description")
private String deliveryDescription;
@Column(name = "data", columnDefinition = "json")
private String messageData;
@ManyToOne
@JoinColumn(name = "schedule_id")
private Schedule schedule;
public Message() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getToNumber() {
return toNumber;
}
public void setToNumber(String toNumber) {
this.toNumber = toNumber;
}
public String getFromNumber() {
return fromNumber;
}
public void setFromNumber(String fromNumber) {
this.fromNumber = fromNumber;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public MessageDirection getDirection() {
return direction;
}
public void setDirection(MessageDirection direction) {
this.direction = direction;
}
public MessageStatus getStatus() {
return status;
}
public void setStatus(MessageStatus status) {
this.status = status;
}
public KeywordType getType() {
return type;
}
public void setType(KeywordType type) {
this.type = type;
}
public Timestamp getGeneratedTime() {
return generatedTime;
}
public void setGeneratedTime(Timestamp generatedTime) {
this.generatedTime = generatedTime;
}
public Timestamp getScheduledTime() {
return scheduledTime;
}
public void setScheduledTime(Timestamp scheduledTime) {
this.scheduledTime = scheduledTime;
}
public Schedule getSchedule() {
return schedule;
}
public void setSchedule(Schedule schedule) {
this.schedule = schedule;
}
public String getKeywordMatched() {
return keywordMatched;
}
public void setKeywordMatched(String keywordMatched) {
this.keywordMatched = keywordMatched;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public MessageReadStatus getReadStatus() {
return readStatus;
}
public void setReadStatus(MessageReadStatus readStatus) {
this.readStatus = readStatus;
}
public String getDeliveryCode() {
return deliveryCode;
}
public void setDeliveryCode(String deliveryCode) {
this.deliveryCode = deliveryCode;
}
public String getMessageData() {
return messageData;
}
public void setMessageData(String messageData) {
this.messageData = messageData;
}
public String getDeliveryDescription() {
return deliveryDescription;
}
public void setDeliveryDescription(String deliveryDescription) {
this.deliveryDescription = deliveryDescription;
}
}
为什么要更换它。我怎样才能以正确的方式编写查询?
解决方法是使用countQuery
注解参数:
public interface Repository extends JpaRepository<Entity, Long> {
String QUERY = "FROM entity " +
" WHERE name ILIKE :name ";
@Query(
value = "SELECT * " + QUERY,
countQuery = "SELECT count(*) " + QUERY,
nativeQuery = true
)
Page<KDeploymentView> findBy(
@Param("name") String name,
Pageable p
);