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