使用分页时,spring jpa本机查询中的'select count(*)from'被'select count(where)'替换

时间:2019-07-24 06:33:26

标签: java spring spring-data-jpa nativequery

我在JPA存储库中的@Query注释中使用本机查询

    @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) 消息表的实体类在这里。

    @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;
        }
    }

为什么要更换它。如何以正确的方式编写查询?

1 个答案:

答案 0 :(得分:1)

解决方案是使用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
);