代码之家  ›  专栏  ›  技术社区  ›  Michael Coxon

Spring数据排序数组或设置为可分页

  •  1
  • Michael Coxon  · 技术社区  · 7 年前

    我有一个(或一组)AirforhinesDirective的列表:

    @Entity
    public class AirworthinessDirective {
    
        @Id
        private String issueNumber;
    
        private String casaCode;
    
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-d")
        private LocalDate issueDate;
    
        private String title;
    
        private boolean isCancelled;
    
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-d")
        private LocalDate effective;
    
        @Column(columnDefinition = "TEXT")
        private String applicability;
    
        private AdRecurrence period;
    
        private String file;
    
        public AirworthinessDirective() {
        }
    
        public static AirworthinessDirective of(String issueNumber, String casaCode, LocalDate issueDate, String title, boolean isCancelled, LocalDate effective, String applicability, AdRecurrence period, String file) {
    
            AirworthinessDirective ad = new AirworthinessDirective();
            ad.issueNumber = issueNumber;
            ad.casaCode = casaCode;
            ad.issueDate = issueDate;
            ad.title = title;
            ad.isCancelled = isCancelled;
            ad.effective = effective;
            ad.applicability = applicability;
            ad.period = period;
            ad.file = file;
            return ad;
        }
    
        // accessors, equals, hashcode and builder ommitted
    }
    

    我要排序的两个字段是issuenumber和iscancelled。

    我有这种服务方法:

    public Page<AirworthinessDirective> formPagedAds(int pg, List<AirworthinessDirective> ads) {
        Pageable pageable = PageRequest.of(pg, 10, standardAdSorting());
        int start = Math.toIntExact(pageable.getOffset());
        int end = (start + pageable.getPageSize()) > ads.size() ? ads.size() : (start + pageable.getPageSize());
        return new PageImpl<>(ads.subList(start, end), pageable, ads.size());
    }
    

    同样的事情也可以用一组适航指令来代替。我尝试了两种方法,因为我认为这套设备的顺序可能不正确(但这不是原因)。这个 standardADSorting() 方法如下:

        private Sort standardAdSorting() {
            List<Sort.Order> sortOrders = new ArrayList<>();
            sortOrders.add(Sort.Order.asc("isCancelled"));
            sortOrders.add(Sort.Order.desc("issueNumber"));
            return Sort.by(sortOrders);
        }
    

    正如我希望您能看到的,它的目的是首先按取消字段排序,然后按issuenumber字段排序。换言之,我希望所有取消的广告都放在后面,否则,请按发行号订购。

    我发现,当设置了可分页时,当我运行此测试时,没有任何排序实际发生:

    @RunWith(SpringRunner.class)
    @ActiveProfiles("embedded")
    public class MaintenanceContractServiceTest {
    
        @Autowired
        private MaintenanceContractService.Default service;
    
        @Test
        public void formPagedAds_withUnsortedADs() {
    
            List<AirworthinessDirective> ads = new ArrayList<>();
    
            ads.add(AirworthinessDirective.of("AD/PA-31/75", "PA-31", LocalDate.of(2006, 12, 31),
                    "King KFC 300 Autopilot Yaw Bridle Cable Clamps - Replacement - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/2009-13-06R1", "PA-31", null,
                    "Forward Baggage Door Locking Mechanism - Inspection / Modification", false, LocalDate.of(2011, 11, 2),
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/33", "PA-31", LocalDate.of(2006, 12, 31),
                    "Exhaust System Couplings - Inspection - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/104", "PA-31", LocalDate.of(2006, 12, 31),
                    "Elevator Outboard Hinge Installation - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/97 Amdt 2", "PA-31", LocalDate.of(2006, 12, 31),
                    "Horizontal Stabiliser and Elevator Outboard Hinge", false, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/99 Amdt 1", "PA-31", LocalDate.of(2006, 12, 31),
                    "Elevator Control Tube - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/90", "PA-31", LocalDate.of(2006, 12, 31),
                    "Rudder Trim Mechanism - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/131", "PA-31", LocalDate.of(2006, 12, 31),
                    "Nose Baggage Door - CANCELLED", true, null,
                    null, null, "http://services.casa..."));
            ads.add(AirworthinessDirective.of("AD/PA-31/2016-08-18 (Correction)", "PA-31", null,
                    "Inspection of the Fuel Hose Assembly and Turbocharger Support Assembly Clearance", false, LocalDate.of(2016, 6, 5),
                    null, null, "http://services.casa..."));
    
            Page<AirworthinessDirective> page = service.formPagedAds(0, ads);
    
            assertThat(page, is(notNullValue()));
            assertThat(page.getTotalPages(), is(1));
            assertThat(page.getTotalElements(), is(9L));
            assertThat(page.getContent(), is(notNullValue()));
            assertThat(page.getContent().size(), is(9));
    
            // all asserts relating to ordering fail, basically everything is
            // in input order.
        }
    }
    

    有人知道我要做什么才能得到我想要的排序吗?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Michael Coxon    7 年前

    在jb nizet的帮助下,我能够使用比较器解决这个问题,而不是使用spring数据进行排序。归根结底是改变 formPagedAds() 方法:

        public Page<AirworthinessDirective> formPagedAds(int pg, List<AirworthinessDirective> ads) {
            ads.sort(
                    Comparator
                    .comparing(AirworthinessDirective::isCancelled)
                    .thenComparing(AirworthinessDirective::getIssueNumber)
            );
    
            Pageable pageable = PageRequest.of(pg, 10, Sort.unsorted());
            int start = Math.toIntExact(pageable.getOffset());
            int end = (start + pageable.getPageSize()) > ads.size() ? ads.size() : (start + pageable.getPageSize());
            return new PageImpl<>(ads.subList(start, end), pageable, ads.size());
        }