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 totalPage = INIT_VALUE; 058 059 /** 060 * 总数据数量。 061 */ 062 private long totalRow = INIT_VALUE; 063 064 /** 065 * 是否优化分页查询 COUNT 语句。 066 */ 067 private boolean optimizeCountQuery = true; 068 069 /** 070 * 创建分页对象。 071 * 072 * @param pageNumber 当前页码 073 * @param pageSize 每页数据数量 074 * @param <T> 数据类型 075 * @return 分页对象 076 */ 077 public static <T> Page<T> of(Number pageNumber, Number pageSize) { 078 return new Page<>(pageNumber, pageSize); 079 } 080 081 /** 082 * 创建分页对象。 083 * 084 * @param pageNumber 当前页码 085 * @param pageSize 每页数据数量 086 * @param totalRow 总数据数量 087 * @param <T> 数据类型 088 * @return 分页对象 089 */ 090 public static <T> Page<T> of(Number pageNumber, Number pageSize, Number totalRow) { 091 return new Page<>(pageNumber, pageSize, totalRow); 092 } 093 094 /** 095 * 创建分页对象。 096 */ 097 public Page() { 098 } 099 100 /** 101 * 创建分页对象。 102 * 103 * @param pageNumber 当前页码 104 * @param pageSize 每页数据数量 105 */ 106 public Page(Number pageNumber, Number pageSize) { 107 this.setPageNumber(pageNumber.longValue()); 108 this.setPageSize(pageSize.longValue()); 109 } 110 111 /** 112 * 创建分页对象。 113 * 114 * @param pageNumber 当前页码 115 * @param pageSize 每页数据数量 116 * @param totalRow 总数居数量 117 */ 118 public Page(Number pageNumber, Number pageSize, Number totalRow) { 119 this.setPageNumber(pageNumber.longValue()); 120 this.setPageSize(pageSize.longValue()); 121 this.setTotalRow(totalRow.longValue()); 122 } 123 124 /** 125 * 创建分页对象。 126 * 127 * @param records 当前页数据 128 * @param pageNumber 当前页码 129 * @param pageSize 每页数据数量 130 * @param totalRow 总数居数量 131 */ 132 public Page(List<T> records, Number pageNumber, Number pageSize, Number totalRow) { 133 this.setRecords(records); 134 this.setPageNumber(pageNumber.longValue()); 135 this.setPageSize(pageSize.longValue()); 136 this.setTotalRow(totalRow.longValue()); 137 } 138 139 /** 140 * 获取当前页的数据。 141 * 142 * @return 当前页的数据 143 */ 144 public List<T> getRecords() { 145 return records; 146 } 147 148 /** 149 * 设置当前页的数据。 150 * 151 * @param records 当前页的数据 152 */ 153 public void setRecords(List<T> records) { 154 if (records == null) { 155 records = Collections.emptyList(); 156 } 157 this.records = records; 158 } 159 160 /** 161 * 获取当前页码。 162 * 163 * @return 页码 164 */ 165 public long getPageNumber() { 166 return pageNumber; 167 } 168 169 /** 170 * 设置当前页码。 171 * 172 * @param pageNumber 页码 173 */ 174 public void setPageNumber(long pageNumber) { 175 if (pageNumber < 1) { 176 throw new IllegalArgumentException("pageNumber must greater than or equal 1,current value is: " + pageNumber); 177 } 178 this.pageNumber = pageNumber; 179 } 180 181 /** 182 * 获取当前每页数据数量。 183 * 184 * @return 每页数据数量 185 */ 186 public long getPageSize() { 187 return pageSize; 188 } 189 190 /** 191 * 设置当前每页数据数量。 192 * 193 * @param pageSize 每页数据数量 194 */ 195 public void setPageSize(long pageSize) { 196 if (pageSize < 0) { 197 throw new IllegalArgumentException("pageSize must greater than or equal 0,current value is: " + pageSize); 198 } 199 this.pageSize = pageSize; 200 this.calcTotalPage(); 201 } 202 203 /** 204 * 获取数据总数。 205 * 206 * @return 数据总数 207 */ 208 public long getTotalPage() { 209 return totalPage; 210 } 211 212 /** 213 * 设置总页数。 214 * 215 * @param totalPage 总页数 216 */ 217 public void setTotalPage(long totalPage) { 218 this.totalPage = totalPage; 219 } 220 221 /** 222 * 获取数据总数。 223 * 224 * @return 数据总数 225 */ 226 public long getTotalRow() { 227 return totalRow; 228 } 229 230 /** 231 * 设置数据总数。 232 * 233 * @param totalRow 数据总数 234 */ 235 public void setTotalRow(long totalRow) { 236 this.totalRow = totalRow; 237 this.calcTotalPage(); 238 } 239 240 /** 241 * 计算总页码。 242 */ 243 private void calcTotalPage() { 244 if (pageSize < 0 || totalRow < 0) { 245 totalPage = INIT_VALUE; 246 } else { 247 totalPage = totalRow % pageSize == 0 ? (totalRow / pageSize) : (totalRow / pageSize + 1); 248 } 249 } 250 251 /** 252 * 当前页是否有记录(有内容)。 253 * 254 * @return {@code true} 有内容,{@code false} 没有内容 255 */ 256 public boolean hasRecords() { 257 return getTotalRow() > 0 && getPageNumber() <= getTotalPage(); 258 } 259 260 /** 261 * 是否存在下一页。 262 * 263 * @return {@code true} 存在下一页,{@code false} 不存在下一页 264 */ 265 public boolean hasNext() { 266 return getTotalPage() != 0 && getPageNumber() < getTotalPage(); 267 } 268 269 /** 270 * 是否存在上一页。 271 * 272 * @return {@code true} 存在上一页,{@code false} 不存在上一页 273 */ 274 public boolean hasPrevious() { 275 return getPageNumber() > 1; 276 } 277 278 /** 279 * 获取当前分页偏移量。 280 * 281 * @return 偏移量 282 */ 283 public long offset() { 284 return getPageSize() * (getPageNumber() - 1); 285 } 286 287 /** 288 * 设置是否自动优化 COUNT 查询语句。 289 * 290 * @param optimizeCountQuery 是否优化 291 */ 292 public void setOptimizeCountQuery(boolean optimizeCountQuery) { 293 this.optimizeCountQuery = optimizeCountQuery; 294 } 295 296 /** 297 * 是否自动优化 COUNT 查询语句(默认优化)。 298 * 299 * @return {@code true} 优化,{@code false} 不优化 300 */ 301 public boolean needOptimizeCountQuery() { 302 return optimizeCountQuery; 303 } 304 305 public <R> Page<R> map(Function<? super T, ? extends R> mapper) { 306 Page<R> newPage = new Page<>(); 307 newPage.pageNumber = pageNumber; 308 newPage.pageSize = pageSize; 309 newPage.totalPage = totalPage; 310 newPage.totalRow = totalRow; 311 312 if (records != null && !records.isEmpty()) { 313 List<R> newRecords = new ArrayList<>(records.size()); 314 for (T t : records) { 315 newRecords.add(mapper.apply(t)); 316 } 317 newPage.records = newRecords; 318 } 319 return newPage; 320 } 321 322 @Override 323 public String toString() { 324 return "Page{" + 325 "pageNumber=" + pageNumber + 326 ", pageSize=" + pageSize + 327 ", totalPage=" + totalPage + 328 ", totalRow=" + totalRow + 329 ", records=" + records + 330 '}'; 331 } 332 333}