IService.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /*
  2. * Copyright (c) 2011-2022, baomidou (jobob@qq.com).
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.baomidou.mybatisplus.extension.service;
  17. import com.baomidou.mybatisplus.core.conditions.Wrapper;
  18. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  19. import com.baomidou.mybatisplus.core.metadata.IPage;
  20. import com.baomidou.mybatisplus.core.toolkit.Assert;
  21. import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  22. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  23. import com.baomidou.mybatisplus.extension.conditions.query.ChainQuery;
  24. import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
  25. import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
  26. import com.baomidou.mybatisplus.extension.conditions.update.ChainUpdate;
  27. import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
  28. import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
  29. import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper;
  30. import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper;
  31. import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
  32. import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
  33. import org.springframework.transaction.annotation.Transactional;
  34. import java.io.Serializable;
  35. import java.util.Collection;
  36. import java.util.List;
  37. import java.util.Map;
  38. import java.util.Objects;
  39. import java.util.function.Function;
  40. import java.util.stream.Collectors;
  41. /**
  42. * 顶级 Service
  43. *
  44. * @author hubin
  45. * @since 2018-06-23
  46. */
  47. public interface IService<T> {
  48. /**
  49. * 默认批次提交数量
  50. */
  51. int DEFAULT_BATCH_SIZE = 1000;
  52. /**
  53. * 插入一条记录(选择字段,策略插入)
  54. *
  55. * @param entity 实体对象
  56. */
  57. default boolean save(T entity) {
  58. return SqlHelper.retBool(getBaseMapper().insert(entity));
  59. }
  60. /**
  61. * 插入(批量)
  62. *
  63. * @param entityList 实体对象集合
  64. */
  65. @Transactional(rollbackFor = Exception.class)
  66. default boolean saveBatch(Collection<T> entityList) {
  67. return saveBatch(entityList, DEFAULT_BATCH_SIZE);
  68. }
  69. /**
  70. * 插入(批量)
  71. *
  72. * @param entityList 实体对象集合
  73. * @param batchSize 插入批次数量
  74. */
  75. boolean saveBatch(Collection<T> entityList, int batchSize);
  76. /**
  77. * 批量修改插入
  78. *
  79. * @param entityList 实体对象集合
  80. */
  81. @Transactional(rollbackFor = Exception.class)
  82. default boolean saveOrUpdateBatch(Collection<T> entityList) {
  83. return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
  84. }
  85. /**
  86. * 批量修改插入
  87. *
  88. * @param entityList 实体对象集合
  89. * @param batchSize 每次的数量
  90. */
  91. boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
  92. /**
  93. * 根据 ID 删除
  94. *
  95. * @param id 主键ID
  96. */
  97. default boolean removeById(Serializable id) {
  98. return SqlHelper.retBool(getBaseMapper().deleteById(id));
  99. }
  100. /**
  101. * 根据 ID 删除
  102. *
  103. * @param id 主键(类型必须与实体类型字段保持一致)
  104. * @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
  105. * @return 删除结果
  106. * @since 3.5.0
  107. */
  108. default boolean removeById(Serializable id, boolean useFill) {
  109. throw new UnsupportedOperationException("不支持的方法!");
  110. }
  111. /**
  112. * 根据实体(ID)删除
  113. *
  114. * @param entity 实体
  115. * @since 3.4.4
  116. */
  117. default boolean removeById(T entity) {
  118. return SqlHelper.retBool(getBaseMapper().deleteById(entity));
  119. }
  120. /**
  121. * 根据 columnMap 条件,删除记录
  122. *
  123. * @param columnMap 表字段 map 对象
  124. */
  125. default boolean removeByMap(Map<String, Object> columnMap) {
  126. Assert.notEmpty(columnMap, "error: columnMap must not be empty");
  127. return SqlHelper.retBool(getBaseMapper().deleteByMap(columnMap));
  128. }
  129. /**
  130. * 根据 entity 条件,删除记录
  131. *
  132. * @param queryWrapper 实体包装类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  133. */
  134. default boolean remove(Wrapper<T> queryWrapper) {
  135. return SqlHelper.retBool(getBaseMapper().delete(queryWrapper));
  136. }
  137. /**
  138. * 删除(根据ID 批量删除)
  139. *
  140. * @param list 主键ID或实体列表
  141. */
  142. default boolean removeByIds(Collection<?> list) {
  143. if (CollectionUtils.isEmpty(list)) {
  144. return false;
  145. }
  146. return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
  147. }
  148. /**
  149. * 批量删除
  150. *
  151. * @param list 主键ID或实体列表
  152. * @param useFill 是否填充(为true的情况,会将入参转换实体进行delete删除)
  153. * @return 删除结果
  154. * @since 3.5.0
  155. */
  156. @Transactional(rollbackFor = Exception.class)
  157. default boolean removeByIds(Collection<?> list, boolean useFill) {
  158. if (CollectionUtils.isEmpty(list)) {
  159. return false;
  160. }
  161. if (useFill) {
  162. return removeBatchByIds(list, true);
  163. }
  164. return SqlHelper.retBool(getBaseMapper().deleteBatchIds(list));
  165. }
  166. /**
  167. * 批量删除(jdbc批量提交)
  168. *
  169. * @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
  170. * @return 删除结果
  171. * @since 3.5.0
  172. */
  173. @Transactional(rollbackFor = Exception.class)
  174. default boolean removeBatchByIds(Collection<?> list) {
  175. return removeBatchByIds(list, DEFAULT_BATCH_SIZE);
  176. }
  177. /**
  178. * 批量删除(jdbc批量提交)
  179. *
  180. * @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)
  181. * @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
  182. * @return 删除结果
  183. * @since 3.5.0
  184. */
  185. @Transactional(rollbackFor = Exception.class)
  186. default boolean removeBatchByIds(Collection<?> list, boolean useFill) {
  187. return removeBatchByIds(list, DEFAULT_BATCH_SIZE, useFill);
  188. }
  189. /**
  190. * 批量删除(jdbc批量提交)
  191. *
  192. * @param list 主键ID或实体列表
  193. * @param batchSize 批次大小
  194. * @return 删除结果
  195. * @since 3.5.0
  196. */
  197. default boolean removeBatchByIds(Collection<?> list, int batchSize) {
  198. throw new UnsupportedOperationException("不支持的方法!");
  199. }
  200. /**
  201. * 批量删除(jdbc批量提交)
  202. *
  203. * @param list 主键ID或实体列表
  204. * @param batchSize 批次大小
  205. * @param useFill 是否启用填充(为true的情况,会将入参转换实体进行delete删除)
  206. * @return 删除结果
  207. * @since 3.5.0
  208. */
  209. default boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {
  210. throw new UnsupportedOperationException("不支持的方法!");
  211. }
  212. /**
  213. * 根据 ID 选择修改
  214. *
  215. * @param entity 实体对象
  216. */
  217. default boolean updateById(T entity) {
  218. return SqlHelper.retBool(getBaseMapper().updateById(entity));
  219. }
  220. /**
  221. * 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
  222. *
  223. * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
  224. */
  225. default boolean update(Wrapper<T> updateWrapper) {
  226. return update(null, updateWrapper);
  227. }
  228. /**
  229. * 根据 whereEntity 条件,更新记录
  230. *
  231. * @param entity 实体对象
  232. * @param updateWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper}
  233. */
  234. default boolean update(T entity, Wrapper<T> updateWrapper) {
  235. return SqlHelper.retBool(getBaseMapper().update(entity, updateWrapper));
  236. }
  237. /**
  238. * 根据ID 批量更新
  239. *
  240. * @param entityList 实体对象集合
  241. */
  242. @Transactional(rollbackFor = Exception.class)
  243. default boolean updateBatchById(Collection<T> entityList) {
  244. return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
  245. }
  246. /**
  247. * 根据ID 批量更新
  248. *
  249. * @param entityList 实体对象集合
  250. * @param batchSize 更新批次数量
  251. */
  252. boolean updateBatchById(Collection<T> entityList, int batchSize);
  253. /**
  254. * TableId 注解存在更新记录,否插入一条记录
  255. *
  256. * @param entity 实体对象
  257. */
  258. boolean saveOrUpdate(T entity);
  259. /**
  260. * 根据 ID 查询
  261. *
  262. * @param id 主键ID
  263. */
  264. default T getById(Serializable id) {
  265. return getBaseMapper().selectById(id);
  266. }
  267. /**
  268. * 查询(根据ID 批量查询)
  269. *
  270. * @param idList 主键ID列表
  271. */
  272. default List<T> listByIds(Collection<? extends Serializable> idList) {
  273. return getBaseMapper().selectBatchIds(idList);
  274. }
  275. /**
  276. * 查询(根据 columnMap 条件)
  277. *
  278. * @param columnMap 表字段 map 对象
  279. */
  280. default List<T> listByMap(Map<String, Object> columnMap) {
  281. return getBaseMapper().selectByMap(columnMap);
  282. }
  283. /**
  284. * 根据 Wrapper,查询一条记录 <br/>
  285. * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
  286. *
  287. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  288. */
  289. default T getOne(Wrapper<T> queryWrapper) {
  290. return getOne(queryWrapper, true);
  291. }
  292. /**
  293. * 根据 Wrapper,查询一条记录
  294. *
  295. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  296. * @param throwEx 有多个 result 是否抛出异常
  297. */
  298. T getOne(Wrapper<T> queryWrapper, boolean throwEx);
  299. /**
  300. * 根据 Wrapper,查询一条记录
  301. *
  302. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  303. */
  304. Map<String, Object> getMap(Wrapper<T> queryWrapper);
  305. /**
  306. * 根据 Wrapper,查询一条记录
  307. *
  308. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  309. * @param mapper 转换函数
  310. */
  311. <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
  312. /**
  313. * 查询总记录数
  314. *
  315. * @see Wrappers#emptyWrapper()
  316. */
  317. default long count() {
  318. return count(Wrappers.emptyWrapper());
  319. }
  320. /**
  321. * 根据 Wrapper 条件,查询总记录数
  322. *
  323. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  324. */
  325. default long count(Wrapper<T> queryWrapper) {
  326. return SqlHelper.retCount(getBaseMapper().selectCount(queryWrapper));
  327. }
  328. /**
  329. * 查询列表
  330. *
  331. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  332. */
  333. default List<T> list(Wrapper<T> queryWrapper) {
  334. return getBaseMapper().selectList(queryWrapper);
  335. }
  336. /**
  337. * 查询所有
  338. *
  339. * @see Wrappers#emptyWrapper()
  340. */
  341. default List<T> list() {
  342. return list(Wrappers.emptyWrapper());
  343. }
  344. /**
  345. * 翻页查询
  346. *
  347. * @param page 翻页对象
  348. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  349. */
  350. default <E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper) {
  351. return getBaseMapper().selectPage(page, queryWrapper);
  352. }
  353. /**
  354. * 无条件翻页查询
  355. *
  356. * @param page 翻页对象
  357. * @see Wrappers#emptyWrapper()
  358. */
  359. default <E extends IPage<T>> E page(E page) {
  360. return page(page, Wrappers.emptyWrapper());
  361. }
  362. /**
  363. * 查询列表
  364. *
  365. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  366. */
  367. default List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper) {
  368. return getBaseMapper().selectMaps(queryWrapper);
  369. }
  370. /**
  371. * 查询所有列表
  372. *
  373. * @see Wrappers#emptyWrapper()
  374. */
  375. default List<Map<String, Object>> listMaps() {
  376. return listMaps(Wrappers.emptyWrapper());
  377. }
  378. /**
  379. * 查询全部记录
  380. */
  381. default List<Object> listObjs() {
  382. return listObjs(Function.identity());
  383. }
  384. /**
  385. * 查询全部记录
  386. *
  387. * @param mapper 转换函数
  388. */
  389. default <V> List<V> listObjs(Function<? super Object, V> mapper) {
  390. return listObjs(Wrappers.emptyWrapper(), mapper);
  391. }
  392. /**
  393. * 根据 Wrapper 条件,查询全部记录
  394. *
  395. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  396. */
  397. default List<Object> listObjs(Wrapper<T> queryWrapper) {
  398. return listObjs(queryWrapper, Function.identity());
  399. }
  400. /**
  401. * 根据 Wrapper 条件,查询全部记录
  402. *
  403. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  404. * @param mapper 转换函数
  405. */
  406. default <V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
  407. return getBaseMapper().selectObjs(queryWrapper).stream().filter(Objects::nonNull).map(mapper).collect(Collectors.toList());
  408. }
  409. /**
  410. * 翻页查询
  411. *
  412. * @param page 翻页对象
  413. * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
  414. */
  415. default <E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper) {
  416. return getBaseMapper().selectMapsPage(page, queryWrapper);
  417. }
  418. /**
  419. * 无条件翻页查询
  420. *
  421. * @param page 翻页对象
  422. * @see Wrappers#emptyWrapper()
  423. */
  424. default <E extends IPage<Map<String, Object>>> E pageMaps(E page) {
  425. return pageMaps(page, Wrappers.emptyWrapper());
  426. }
  427. /**
  428. * 获取对应 entity 的 BaseMapper
  429. *
  430. * @return BaseMapper
  431. */
  432. BaseMapper<T> getBaseMapper();
  433. /**
  434. * 获取 entity 的 class
  435. *
  436. * @return {@link Class<T>}
  437. */
  438. Class<T> getEntityClass();
  439. /**
  440. * 以下的方法使用介绍:
  441. *
  442. * 一. 名称介绍
  443. * 1. 方法名带有 query 的为对数据的查询操作, 方法名带有 update 的为对数据的修改操作
  444. * 2. 方法名带有 lambda 的为内部方法入参 column 支持函数式的
  445. * 二. 支持介绍
  446. *
  447. * 1. 方法名带有 query 的支持以 {@link ChainQuery} 内部的方法名结尾进行数据查询操作
  448. * 2. 方法名带有 update 的支持以 {@link ChainUpdate} 内部的方法名为结尾进行数据修改操作
  449. *
  450. * 三. 使用示例,只用不带 lambda 的方法各展示一个例子,其他类推
  451. * 1. 根据条件获取一条数据: `query().eq("column", value).one()`
  452. * 2. 根据条件删除一条数据: `update().eq("column", value).remove()`
  453. *
  454. */
  455. /**
  456. * 链式查询 普通
  457. *
  458. * @return QueryWrapper 的包装类
  459. */
  460. default QueryChainWrapper<T> query() {
  461. return ChainWrappers.queryChain(getBaseMapper());
  462. }
  463. /**
  464. * 链式查询 lambda 式
  465. * <p>注意:不支持 Kotlin </p>
  466. *
  467. * @return LambdaQueryWrapper 的包装类
  468. */
  469. default LambdaQueryChainWrapper<T> lambdaQuery() {
  470. return ChainWrappers.lambdaQueryChain(getBaseMapper(), getEntityClass());
  471. }
  472. /**
  473. * 链式查询 lambda 式
  474. * <p>注意:不支持 Kotlin </p>
  475. *
  476. * @param entity 实体对象
  477. * @return LambdaQueryWrapper 的包装类
  478. */
  479. default LambdaQueryChainWrapper<T> lambdaQuery(T entity) {
  480. return ChainWrappers.lambdaQueryChain(getBaseMapper(), entity);
  481. }
  482. /**
  483. * 链式查询 lambda 式
  484. * kotlin 使用
  485. *
  486. * @return KtQueryWrapper 的包装类
  487. */
  488. default KtQueryChainWrapper<T> ktQuery() {
  489. return ChainWrappers.ktQueryChain(getBaseMapper(), getEntityClass());
  490. }
  491. /**
  492. * 链式查询 lambda 式
  493. * kotlin 使用
  494. *
  495. * @return KtQueryWrapper 的包装类
  496. */
  497. default KtUpdateChainWrapper<T> ktUpdate() {
  498. return ChainWrappers.ktUpdateChain(getBaseMapper(), getEntityClass());
  499. }
  500. /**
  501. * 链式更改 普通
  502. *
  503. * @return UpdateWrapper 的包装类
  504. */
  505. default UpdateChainWrapper<T> update() {
  506. return ChainWrappers.updateChain(getBaseMapper());
  507. }
  508. /**
  509. * 链式更改 lambda 式
  510. * <p>注意:不支持 Kotlin </p>
  511. *
  512. * @return LambdaUpdateWrapper 的包装类
  513. */
  514. default LambdaUpdateChainWrapper<T> lambdaUpdate() {
  515. return ChainWrappers.lambdaUpdateChain(getBaseMapper());
  516. }
  517. /**
  518. * <p>
  519. * 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
  520. * 此次修改主要是减少了此项业务代码的代码量(存在性验证之后的saveOrUpdate操作)
  521. * </p>
  522. *
  523. * @param entity 实体对象
  524. */
  525. default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {
  526. return update(entity, updateWrapper) || saveOrUpdate(entity);
  527. }
  528. }