需求大概是这样:对加入到商品分组下的商品按价格或新品(创建时间进行正序或倒序排序)。
特别注意点,如果使用内存分页的话,暂时只想到一次性查出所有的,如果在前面进行分页的话,后面的排序只是当前页的数据进行排序,这样数据是不对的。
public R<Page<AppGoodsGropuInfoVo>> queryAppGoodsGroupList(GoodsGroupRelDTO dto) {
// 先临时存下来分页数据
int current = dto.getCurrent();
int size = dto.getSize();
if (StringUtils.isNotBlank(dto.getOrderByField())) {
if (GoodsConstant.ORDER_BY_NEW_GOODS.equals(dto.getOrderByField()) || GoodsConstant.ORDER_BY_PRICE.equals(dto.getOrderByField())) {
// 如果需要排序方式的话,先查询出所有,然后进行内存排序
dto.setCurrent(1);
dto.setSize(Integer.MAX_VALUE);
}
}
List<AppGoodsGropuInfoVo> appGoodsGroupInfoVos =
goodsGroupRelMapper.queryGoodsGroupRelPageBySortType(PageParam.initial(page, dto), groupGoodsSortTypeDTO);
// 进行内存排序
if (StringUtils.isNotBlank(dto.getOrderByField())) {
if (null == dto.getIsAsc()) {
// 默认按降序排
dto.setIsAsc(false);
}
if (GoodsConstant.ORDER_BY_NEW_GOODS.equals(dto.getOrderByField())) {
// 按新品排序
orderByNewGoods(appGoodsGroupInfoVos, dto.getIsAsc());
}
if (GoodsConstant.ORDER_BY_PRICE.equals(dto.getOrderByField())) {
// 按价格排序
orderByPrice(appGoodsGroupInfoVos, dto.getIsAsc());
}
// 排序完成后,再进行分页处理
int start = (current - 1) * size;
int end = current * size;
if (end > appGoodsGroupInfoVos.size()) {
end = appGoodsGroupInfoVos.size();
}
// 增加一个起始页数量大于记录总数的判断,如果大于总数,则查询出来的记录列表应该为空
if (start > appGoodsGroupInfoVos.size()) {
// 如果分页后的start大于总条数
start = 0;
end = 0;
}
appGoodsGroupInfoVos = appGoodsGroupInfoVos.subList(start, end);
}
Page<AppGoodsGropuInfoVo> result = new Page<>();
result.setRecords(appGoodsGroupInfoVos);
result.setTotal(appGoodsGroupInfoVos.size());
return new R<>(result);
}
/**
* 按新品顺序进行排序
* @param appGoodsGroupInfoVos
* @param isAsc
*/
private void orderByNewGoods(List<AppGoodsGropuInfoVo> appGoodsGroupInfoVos, boolean isAsc) {
if (isAsc) {
// 按时间倒序排,从新到旧
Collections.sort(appGoodsGroupInfoVos, new Comparator<AppGoodsGropuInfoVo>() {
@Override
public int compare(AppGoodsGropuInfoVo goods1, AppGoodsGropuInfoVo goods2) {
if (DateUtils.getIntervalTimeForSeconds(goods1.getCreateTime(), goods2.getCreateTime()) > 0) {
return -1;
} else if (DateUtils.getIntervalTimeForSeconds(goods1.getCreateTime(), goods2.getCreateTime()) == 0) {
return 0;
} else {
return 1;
}
}
});
} else {
// 按时间正序排,从旧到新
Collections.sort(appGoodsGroupInfoVos, new Comparator<AppGoodsGropuInfoVo>() {
@Override
public int compare(AppGoodsGropuInfoVo goods1, AppGoodsGropuInfoVo goods2) {
if (DateUtils.getIntervalTimeForSeconds(goods1.getCreateTime(), goods2.getCreateTime()) > 0) {
return 1;
} else if (DateUtils.getIntervalTimeForSeconds(goods1.getCreateTime(), goods2.getCreateTime()) == 0) {
return 0;
} else {
return -1;
}
}
});
}
}
/**
* 按价格进行排序
* @param appGoodsGroupInfoVos
* @param isAsc
*/
private void orderByPrice(List<AppGoodsGropuInfoVo> appGoodsGroupInfoVos, boolean isAsc) {
if (isAsc) {
// 从小到大
Collections.sort(appGoodsGroupInfoVos, new Comparator<AppGoodsGropuInfoVo>() {
@Override
public int compare(AppGoodsGropuInfoVo goods1, AppGoodsGropuInfoVo goods2) {
if (new BigDecimal(goods1.getPrice()).compareTo(new BigDecimal(goods2.getPrice())) > 0) {
return 1;
} else if (new BigDecimal(goods1.getPrice()).compareTo(new BigDecimal(goods2.getPrice())) == 0) {
return 0;
} else {
return -1;
}
}
});
} else {
// 按价格从大到小
Collections.sort(appGoodsGroupInfoVos, new Comparator<AppGoodsGropuInfoVo>() {
@Override
public int compare(AppGoodsGropuInfoVo goods1, AppGoodsGropuInfoVo goods2) {
if (new BigDecimal(goods1.getPrice()).compareTo(new BigDecimal(goods2.getPrice())) > 0) {
return -1;
} else if (new BigDecimal(goods1.getPrice()).compareTo(new BigDecimal(goods2.getPrice())) == 0) {
return 0;
} else {
return 1;
}
}
});
}
}
计算时间间隔的数据是采用的hutool包的工具类
import com.xiaoleilu.hutool.date.DateUnit;
import com.xiaoleilu.hutool.date.DateUtil;
public class DateUtils {
/**
* 获取两个时间之间间隔的描述(后者比前者大为正数,否则反之)
* @param date1
* @param date2
* @return
*/
public static long getIntervalTimeForSeconds(Date date1, Date date2) {
return DateUtil.between(date1, date2, DateUnit.SECOND, false);
}