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; 017 018import com.mybatisflex.core.exception.FlexExceptions; 019import com.mybatisflex.core.paginate.Page; 020import com.mybatisflex.core.provider.EntitySqlProvider; 021import com.mybatisflex.core.query.QueryColumn; 022import com.mybatisflex.core.query.QueryCondition; 023import com.mybatisflex.core.query.QueryWrapper; 024import com.mybatisflex.core.query.CPI; 025import com.mybatisflex.core.table.TableInfo; 026import com.mybatisflex.core.table.TableInfoFactory; 027import com.mybatisflex.core.util.ObjectUtil; 028import org.apache.ibatis.annotations.*; 029import org.apache.ibatis.builder.annotation.ProviderContext; 030 031import java.io.Serializable; 032import java.util.Collection; 033import java.util.List; 034import java.util.Map; 035 036public interface BaseMapper<T> { 037 038 /** 039 * 插入 entity 数据 040 * 041 * @param entity 实体类 042 * @return 返回影响的行数 043 * @see com.mybatisflex.core.provider.EntitySqlProvider#insert(Map, ProviderContext) 044 */ 045 @InsertProvider(type = EntitySqlProvider.class, method = "insert") 046 int insert(@Param(FlexConsts.ENTITY) T entity); 047 048 049 /** 050 * 批量插入 entity 数据,只会根据第一条数据来构建插入的字段内容 051 * 052 * @param entities 插入的数据列表 053 * @return 返回影响的行数 054 * @see com.mybatisflex.core.provider.EntitySqlProvider#insertBatch(Map, ProviderContext) 055 * @see com.mybatisflex.core.FlexConsts#METHOD_INSERT_BATCH 056 */ 057 @InsertProvider(type = EntitySqlProvider.class, method = FlexConsts.METHOD_INSERT_BATCH) 058 int insertBatch(@Param(FlexConsts.ENTITIES) List<T> entities); 059 060 061 /** 062 * 新增 或者 更新,若主键有值,则更新,若没有主键值,则插入 063 * 064 * @param entity 实体类 065 * @return 返回影响的行数 066 */ 067 default int insertOrUpdate(T entity) { 068 TableInfo tableInfo = TableInfoFactory.ofEntityClass(entity.getClass()); 069 Object[] pkArgs = tableInfo.buildPkSqlArgs(entity); 070 if (pkArgs.length == 0 || pkArgs[0] == null) { 071 return insert(entity); 072 } else { 073 return update(entity); 074 } 075 } 076 077 /** 078 * 根据 id 删除数据 079 * 如果是多个主键的情况下,需要传入数组 new Object[]{100,101} 080 * 081 * @param id 主键数据 082 * @return 返回影响的行数 083 * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteById(Map, ProviderContext) 084 */ 085 @DeleteProvider(type = EntitySqlProvider.class, method = "deleteById") 086 int deleteById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id); 087 088 089 /** 090 * 根据多个 id 批量删除数据 091 * 092 * @param ids ids 列表 093 * @return 返回影响的行数 094 * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteBatchByIds(Map, ProviderContext) 095 */ 096 @DeleteProvider(type = EntitySqlProvider.class, method = "deleteBatchByIds") 097 int deleteBatchByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids); 098 099 100 /** 101 * 根据 map 构建的条件来删除数据 102 * 103 * @param whereConditions 条件 104 * @return 返回影响的行数 105 */ 106 default int deleteByMap(Map<String, Object> whereConditions) { 107 if (ObjectUtil.areNull(whereConditions) || whereConditions.isEmpty()) { 108 throw FlexExceptions.wrap("deleteByMap is not allow empty map."); 109 } 110 return deleteByQuery(QueryWrapper.create().where(whereConditions)); 111 } 112 113 /** 114 * 根据条件来删除数据 115 * 116 * @param condition 条件 117 * @return 返回影响的行数 118 */ 119 default int deleteByCondition(QueryCondition condition) { 120 return deleteByQuery(QueryWrapper.create().where(condition)); 121 } 122 123 /** 124 * 根据 query 构建的条件来数据吗 125 * 126 * @param queryWrapper query 条件 127 * @return 返回影响的行数 128 * @see com.mybatisflex.core.provider.EntitySqlProvider#deleteByQuery(Map, ProviderContext) 129 */ 130 @DeleteProvider(type = EntitySqlProvider.class, method = "deleteByQuery") 131 int deleteByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper); 132 133 134 /** 135 * 根据主键来更新数据,若数据为 null,也会更新到数据库 136 * 137 * @param entity 数据内容,必须包含有主键 138 * @return 返回影响的行数 139 */ 140 default int update(T entity) { 141 return update(entity, true); 142 } 143 144 /** 145 * 根据主键来更新数据到数据库 146 * 147 * @param entity 数据内容 148 * @param ignoreNulls 是否忽略空内容字段 149 * @return 返回影响的行数 150 * @see com.mybatisflex.core.provider.EntitySqlProvider#update(Map, ProviderContext) 151 */ 152 @UpdateProvider(type = EntitySqlProvider.class, method = "update") 153 int update(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls); 154 155 156 /** 157 * 根据 map 构建的条件来更新数据 158 * 159 * @param entity 数据 160 * @param map where 条件内容 161 * @return 返回影响的行数 162 */ 163 default int updateByMap(T entity, Map<String, Object> map) { 164 return updateByQuery(entity, QueryWrapper.create().where(map)); 165 } 166 167 /** 168 * 根据 condition 来更新数据 169 * 170 * @param entity 数据 171 * @param condition 条件 172 * @return 返回影响的行数 173 */ 174 default int updateByCondition(T entity, QueryCondition condition) { 175 return updateByQuery(entity, QueryWrapper.create().where(condition)); 176 } 177 178 /** 179 * 根据 condition 来更新数据 180 * 181 * @param entity 数据 182 * @param ignoreNulls 是否忽略 null 数据,默认为 true 183 * @param condition 条件 184 * @return 返回影响的行数 185 */ 186 default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition condition) { 187 return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(condition)); 188 } 189 190 191 /** 192 * 根据 query 构建的条件来更新数据 193 * 194 * @param entity 数据内容 195 * @param queryWrapper query 条件 196 * @return 返回影响的行数 197 */ 198 199 default int updateByQuery(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper) { 200 return updateByQuery(entity, true, queryWrapper); 201 } 202 203 /** 204 * 根据 query 构建的条件来更新数据 205 * 206 * @param entity 数据内容 207 * @param ignoreNulls 是否忽略空值 208 * @param queryWrapper query 条件 209 * @see com.mybatisflex.core.provider.EntitySqlProvider#updateByQuery(Map, ProviderContext) 210 */ 211 @UpdateProvider(type = EntitySqlProvider.class, method = "updateByQuery") 212 int updateByQuery(@Param(FlexConsts.ENTITY) T entity, @Param(FlexConsts.IGNORE_NULLS) boolean ignoreNulls, @Param(FlexConsts.QUERY) QueryWrapper queryWrapper); 213 214 215 /** 216 * 根据主键来选择数据 217 * 218 * @param id 多个主键 219 * @return entity 220 * @see com.mybatisflex.core.provider.EntitySqlProvider#selectOneById(Map, ProviderContext) 221 */ 222 @SelectProvider(type = EntitySqlProvider.class, method = "selectOneById") 223 T selectOneById(@Param(FlexConsts.PRIMARY_VALUE) Serializable id); 224 225 226 /** 227 * 根据 map 构建的条件来查询数据 228 * 229 * @param whereConditions where 条件 230 * @return entity 数据 231 */ 232 default T selectOneByMap(Map<String, Object> whereConditions) { 233 return selectOneByQuery(QueryWrapper.create().where(whereConditions)); 234 } 235 236 237 /** 238 * 根据 condition 来查询数据 239 * 240 * @param condition 条件 241 * @return 1 条数据 242 */ 243 default T selectOneByCondition(QueryCondition condition) { 244 return selectOneByQuery(QueryWrapper.create().where(condition)); 245 } 246 247 248 /** 249 * 根据 queryWrapper 构建的条件来查询 1 条数据 250 * 251 * @param queryWrapper query 条件 252 * @return entity 数据 253 */ 254 default T selectOneByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper) { 255 List<T> entities = selectListByQuery(queryWrapper.limit(1)); 256 return (entities == null || entities.isEmpty()) ? null : entities.get(0); 257 } 258 259 /** 260 * 根据多个主键来查询多条数据 261 * 262 * @param ids 主键列表 263 * @return 数据列表 264 * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByIds(Map, ProviderContext) 265 */ 266 @SelectProvider(type = EntitySqlProvider.class, method = "selectListByIds") 267 List<T> selectListByIds(@Param(FlexConsts.PRIMARY_VALUE) Collection<? extends Serializable> ids); 268 269 270 /** 271 * 根据 map 来构建查询条件,查询多条数据 272 * 273 * @param whereConditions 条件列表 274 * @return 数据列表 275 */ 276 default List<T> selectListByMap(Map<String, Object> whereConditions) { 277 return selectListByQuery(QueryWrapper.create().where(whereConditions)); 278 } 279 280 281 /** 282 * 根据 map 来构建查询条件,查询多条数据 283 * 284 * @param whereConditions 条件列表 285 * @return 数据列表 286 */ 287 default List<T> selectListByMap(Map<String, Object> whereConditions, int count) { 288 return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count)); 289 } 290 291 292 /** 293 * 根据 condition 来查询数据 294 * 295 * @param condition condition 条件 296 * @return 数据列表 297 */ 298 default List<T> selectListByCondition(QueryCondition condition) { 299 return selectListByQuery(QueryWrapper.create().where(condition)); 300 } 301 302 303 /** 304 * 根据 condition 来查询数据 305 * 306 * @param condition condition 条件 307 * @param count 数据量 308 * @return 数据列表 309 */ 310 default List<T> selectListByCondition(QueryCondition condition, int count) { 311 return selectListByQuery(QueryWrapper.create().where(condition).limit(count)); 312 } 313 314 315 /** 316 * 根据 query 来构建条件查询数据列表 317 * 318 * @param queryWrapper 查询条件 319 * @return 数据列表 320 * @see com.mybatisflex.core.provider.EntitySqlProvider#selectListByQuery(Map, ProviderContext) 321 */ 322 @SelectProvider(type = EntitySqlProvider.class, method = "selectListByQuery") 323 List<T> selectListByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper); 324 325 326 /** 327 * 查询全部数据 328 * 329 * @return 数据列表 330 */ 331 default List<T> selectAll() { 332 return selectListByQuery(new QueryWrapper()); 333 } 334 335 336 /** 337 * 根据条件查询数据总量 338 * 339 * @param condition 条件 340 * @return 数据量 341 */ 342 default long selectCountByCondition(QueryCondition condition) { 343 return selectCountByQuery(QueryWrapper.create().where(condition)); 344 } 345 346 347 /** 348 * 根据 queryWrapper 来查询数据量 349 * 350 * @param queryWrapper 查询包装器 351 * @return 数据量 352 * @see EntitySqlProvider#selectCountByQuery(Map, ProviderContext) 353 */ 354 @SelectProvider(type = EntitySqlProvider.class, method = "selectCountByQuery") 355 long selectCountByQuery(@Param(FlexConsts.QUERY) QueryWrapper queryWrapper); 356 357 358 /** 359 * 分页查询 360 * 361 * @param pageNumber 当前页码 362 * @param pageSize 每页的数据量 363 * @param queryWrapper 查询条件 364 * @return 返回 Page 数据 365 */ 366 default Page<T> paginate(int pageNumber, int pageSize, QueryWrapper queryWrapper) { 367 Page<T> page = new Page<>(pageNumber, pageSize); 368 return paginate(page, queryWrapper); 369 } 370 371 372 /** 373 * 根据条件分页查询 374 * 375 * @param pageNumber 当前页面 376 * @param pageSize 每页的数据量 377 * @param condition 查询条件 378 * @return 返回 Page 数据 379 */ 380 default Page<T> paginate(int pageNumber, int pageSize, QueryCondition condition) { 381 Page<T> page = new Page<>(pageNumber, pageSize); 382 return paginate(page, new QueryWrapper().where(condition)); 383 } 384 385 /** 386 * 分页查询 387 * 388 * @param pageNumber 当前页码 389 * @param pageSize 每页的数据量 390 * @param totalRow 数据总量 391 * @param queryWrapper 查询条件 392 * @return 返回 Page 数据 393 */ 394 default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { 395 Page<T> page = new Page<>(pageNumber, pageSize, totalRow); 396 return paginate(page, queryWrapper); 397 } 398 399 400 /** 401 * 根据条件分页查询 402 * 403 * @param pageNumber 当前页面 404 * @param pageSize 每页的数据量 405 * @param totalRow 数据总量 406 * @param condition 查询条件 407 * @return 返回 Page 数据 408 */ 409 default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryCondition condition) { 410 Page<T> page = new Page<>(pageNumber, pageSize, totalRow); 411 return paginate(page, new QueryWrapper().where(condition)); 412 } 413 414 415 /** 416 * 分页查询 417 * 418 * @param page page,其包含了页码、每页的数据量,可能包含数据总量 419 * @param queryWrapper 查询条件 420 * @return page 数据 421 */ 422 default Page<T> paginate(@Param("page") Page<T> page, @Param("query") QueryWrapper queryWrapper) { 423 424 List<QueryColumn> groupByColumns = null; 425 426 // 只有 totalRow 小于 0 的时候才会去查询总量 427 // 这样方便用户做总数缓存,而非每次都要去查询总量 428 // 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的 429 if (page.getTotalRow() < 0) { 430 groupByColumns = CPI.getGroupByColumns(queryWrapper); 431 //清除group by 去查询数据 432 CPI.setGroupByColumns(queryWrapper, null); 433 long count = selectCountByQuery(queryWrapper); 434 page.setTotalRow(count); 435 } 436 437 if (page.getTotalRow() == 0 || page.getPageNumber() > page.getTotalPage()) { 438 return page; 439 } 440 441 //恢复数量查询清除的 groupBy 442 if (groupByColumns != null) { 443 CPI.setGroupByColumns(queryWrapper, groupByColumns); 444 } 445 446 int offset = page.getPageSize() * (page.getPageNumber() - 1); 447 queryWrapper.limit(offset, page.getPageSize()); 448 List<T> rows = selectListByQuery(queryWrapper); 449 page.setRecords(rows); 450 return page; 451 } 452}