001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.paginate; 017 018import com.mybatisflex.core.FlexGlobalConfig; 019 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.List; 024import java.util.function.Function; 025 026/** 027 * 分页对象封装。 028 * 029 * @param <T> 数据类型 030 * @author 开源海哥 031 * @author 王帅 032 */ 033public class Page<T> implements Serializable { 034 035 private static final long serialVersionUID = 1L; 036 037 public static final int INIT_VALUE = -1; 038 039 /** 040 * 当前页数据。 041 */ 042 private List<T> records = Collections.emptyList(); 043 044 /** 045 * 当前页码。 046 */ 047 private long pageNumber = 1; 048 049 /** 050 * 每页数据数量。 051 */ 052 private long pageSize = FlexGlobalConfig.getDefaultConfig().getDefaultPageSize(); 053 054 /** 055 * 每页数据数量最大限制。 056 */ 057 private long maxPageSize = FlexGlobalConfig.getDefaultConfig().getDefaultMaxPageSize(); 058 059 /** 060 * 总页数。 061 */ 062 private long totalPage = INIT_VALUE; 063 064 /** 065 * 总数据数量。 066 */ 067 private long totalRow = INIT_VALUE; 068 069 /** 070 * 是否优化分页查询 COUNT 语句。 071 */ 072 private boolean optimizeCountQuery = true; 073 074 /** 075 * 创建分页对象。 076 * 077 * @param pageNumber 当前页码 078 * @param pageSize 每页数据数量 079 * @param <T> 数据类型 080 * @return 分页对象 081 */ 082 public static <T> Page<T> of(Number pageNumber, Number pageSize) { 083 return new Page<>(pageNumber, pageSize); 084 } 085 086 /** 087 * 创建分页对象。 088 * 089 * @param pageNumber 当前页码 090 * @param pageSize 每页数据数量 091 * @param totalRow 总数据数量 092 * @param <T> 数据类型 093 * @return 分页对象 094 */ 095 public static <T> Page<T> of(Number pageNumber, Number pageSize, Number totalRow) { 096 return new Page<>(pageNumber, pageSize, totalRow); 097 } 098 099 /** 100 * 创建分页对象。 101 */ 102 public Page() { 103 } 104 105 /** 106 * 创建分页对象。 107 * 108 * @param pageNumber 当前页码 109 * @param pageSize 每页数据数量 110 */ 111 public Page(Number pageNumber, Number pageSize) { 112 this.setPageNumber(pageNumber.longValue()); 113 this.setPageSize(pageSize.longValue()); 114 } 115 116 /** 117 * 创建分页对象。 118 * 119 * @param pageNumber 当前页码 120 * @param pageSize 每页数据数量 121 * @param totalRow 总数居数量 122 */ 123 public Page(Number pageNumber, Number pageSize, Number totalRow) { 124 this.setPageNumber(pageNumber.longValue()); 125 this.setPageSize(pageSize.longValue()); 126 this.setTotalRow(totalRow.longValue()); 127 } 128 129 /** 130 * 创建分页对象。 131 * 132 * @param records 当前页数据 133 * @param pageNumber 当前页码 134 * @param pageSize 每页数据数量 135 * @param totalRow 总数居数量 136 */ 137 public Page(List<T> records, Number pageNumber, Number pageSize, Number totalRow) { 138 this.setRecords(records); 139 this.setPageNumber(pageNumber.longValue()); 140 this.setPageSize(pageSize.longValue()); 141 this.setTotalRow(totalRow.longValue()); 142 } 143 144 /** 145 * 获取当前页的数据。 146 * 147 * @return 当前页的数据 148 */ 149 public List<T> getRecords() { 150 return records; 151 } 152 153 /** 154 * 设置当前页的数据。 155 * 156 * @param records 当前页的数据 157 */ 158 public void setRecords(List<T> records) { 159 if (records == null) { 160 records = Collections.emptyList(); 161 } 162 this.records = records; 163 } 164 165 /** 166 * 获取当前页码。 167 * 168 * @return 页码 169 */ 170 public long getPageNumber() { 171 return pageNumber; 172 } 173 174 /** 175 * 设置当前页码。 176 * 177 * @param pageNumber 页码 178 */ 179 public void setPageNumber(long pageNumber) { 180 if (pageNumber < 1) { 181 throw new IllegalArgumentException("pageNumber must greater than or equal 1,current value is: " + pageNumber); 182 } 183 this.pageNumber = pageNumber; 184 } 185 186 /** 187 * 获取当前每页数据数量。 188 * 189 * @return 每页数据数量 190 */ 191 public long getPageSize() { 192 return pageSize; 193 } 194 195 /** 196 * 设置当前每页数据数量。 197 * 198 * @param pageSize 每页数据数量 199 */ 200 public void setPageSize(long pageSize) { 201 if (pageSize <= 0) { 202 throw new IllegalArgumentException("pageSize must greater than 0,current value is: " + pageSize); 203 } 204 this.pageSize = Math.min(pageSize, maxPageSize); 205 this.calcTotalPage(); 206 } 207 208 /** 209 * 获取数据总数。 210 * 211 * @return 数据总数 212 */ 213 public long getTotalPage() { 214 return totalPage; 215 } 216 217 /** 218 * 设置总页数。 219 * 220 * @param totalPage 总页数 221 */ 222 public void setTotalPage(long totalPage) { 223 this.totalPage = totalPage; 224 } 225 226 /** 227 * 获取数据总数。 228 * 229 * @return 数据总数 230 */ 231 public long getTotalRow() { 232 return totalRow; 233 } 234 235 /** 236 * 设置数据总数。 237 * 238 * @param totalRow 数据总数 239 */ 240 public void setTotalRow(long totalRow) { 241 this.totalRow = totalRow; 242 this.calcTotalPage(); 243 } 244 245 /** 246 * 计算总页码。 247 */ 248 private void calcTotalPage() { 249 if (pageSize < 0 || totalRow < 0) { 250 totalPage = INIT_VALUE; 251 } else { 252 totalPage = totalRow % pageSize == 0 ? (totalRow / pageSize) : (totalRow / pageSize + 1); 253 } 254 } 255 256 /** 257 * 当前页是否有记录(有内容)。 258 * 259 * @return {@code true} 有内容,{@code false} 没有内容 260 */ 261 public boolean hasRecords() { 262 return getTotalRow() > 0 && getPageNumber() <= getTotalPage(); 263 } 264 265 /** 266 * 是否存在下一页。 267 * 268 * @return {@code true} 存在下一页,{@code false} 不存在下一页 269 */ 270 public boolean hasNext() { 271 return getTotalPage() != 0 && getPageNumber() < getTotalPage(); 272 } 273 274 /** 275 * 是否存在上一页。 276 * 277 * @return {@code true} 存在上一页,{@code false} 不存在上一页 278 */ 279 public boolean hasPrevious() { 280 return getPageNumber() > 1; 281 } 282 283 /** 284 * 获取当前分页偏移量。 285 * 286 * @return 偏移量 287 */ 288 public long offset() { 289 return getPageSize() * (getPageNumber() - 1); 290 } 291 292 /** 293 * 设置是否自动优化 COUNT 查询语句。 294 * 295 * @param optimizeCountQuery 是否优化 296 */ 297 public void setOptimizeCountQuery(boolean optimizeCountQuery) { 298 this.optimizeCountQuery = optimizeCountQuery; 299 } 300 301 /** 302 * 是否自动优化 COUNT 查询语句(默认优化)。 303 * 304 * @return {@code true} 优化,{@code false} 不优化 305 */ 306 public boolean needOptimizeCountQuery() { 307 return optimizeCountQuery; 308 } 309 310 public <R> Page<R> map(Function<? super T, ? extends R> mapper) { 311 Page<R> newPage = new Page<>(); 312 newPage.pageNumber = pageNumber; 313 newPage.pageSize = pageSize; 314 newPage.totalPage = totalPage; 315 newPage.totalRow = totalRow; 316 317 if (records != null && !records.isEmpty()) { 318 List<R> newRecords = new ArrayList<>(records.size()); 319 for (T t : records) { 320 newRecords.add(mapper.apply(t)); 321 } 322 newPage.records = newRecords; 323 } 324 return newPage; 325 } 326 327 @Override 328 public String toString() { 329 return "Page{" + 330 "pageNumber=" + pageNumber + 331 ", pageSize=" + pageSize + 332 ", totalPage=" + totalPage + 333 ", totalRow=" + totalRow + 334 ", records=" + records + 335 '}'; 336 } 337 338}