ServiceImpl.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. /**
  2. * Copyright (c) 2011-2016, hubin (jobob@qq.com).
  3. * <p>
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. * <p>
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * <p>
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.baomidou.mybatisplus.service.impl;
  17. import java.io.Serializable;
  18. import java.util.List;
  19. import java.util.Map;
  20. import org.apache.ibatis.binding.MapperMethod;
  21. import org.apache.ibatis.logging.Log;
  22. import org.apache.ibatis.logging.LogFactory;
  23. import org.apache.ibatis.session.SqlSession;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import com.baomidou.mybatisplus.entity.TableInfo;
  27. import com.baomidou.mybatisplus.enums.SqlMethod;
  28. import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
  29. import com.baomidou.mybatisplus.mapper.BaseMapper;
  30. import com.baomidou.mybatisplus.mapper.Condition;
  31. import com.baomidou.mybatisplus.mapper.SqlHelper;
  32. import com.baomidou.mybatisplus.mapper.Wrapper;
  33. import com.baomidou.mybatisplus.plugins.Page;
  34. import com.baomidou.mybatisplus.service.IService;
  35. import com.baomidou.mybatisplus.toolkit.CollectionUtils;
  36. import com.baomidou.mybatisplus.toolkit.MapUtils;
  37. import com.baomidou.mybatisplus.toolkit.ReflectionKit;
  38. import com.baomidou.mybatisplus.toolkit.StringUtils;
  39. import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
  40. /**
  41. * <p>
  42. * IService 实现类( 泛型:M 是 mapper 对象,T 是实体 , PK 是主键泛型 )
  43. * </p>
  44. *
  45. * @author hubin
  46. * @Date 2016-04-20
  47. */
  48. public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
  49. private static final Log logger = LogFactory.getLog(ServiceImpl.class);
  50. @Autowired
  51. protected M baseMapper;
  52. /**
  53. * <p>
  54. * 判断数据库操作是否成功
  55. * </p>
  56. * <p>
  57. * 注意!! 该方法为 Integer 判断,不可传入 int 基本类型
  58. * </p>
  59. *
  60. * @param result 数据库操作返回影响条数
  61. * @return boolean
  62. */
  63. protected static boolean retBool(Integer result) {
  64. return SqlHelper.retBool(result);
  65. }
  66. @SuppressWarnings("unchecked")
  67. protected Class<T> currentModelClass() {
  68. return ReflectionKit.getSuperClassGenricType(getClass(), 1);
  69. }
  70. /**
  71. * <p>
  72. * 批量操作 SqlSession
  73. * </p>
  74. */
  75. protected SqlSession sqlSessionBatch() {
  76. return SqlHelper.sqlSessionBatch(currentModelClass());
  77. }
  78. /**
  79. * 获取SqlStatement
  80. *
  81. * @param sqlMethod
  82. * @return
  83. */
  84. protected String sqlStatement(SqlMethod sqlMethod) {
  85. return SqlHelper.table(currentModelClass()).getSqlStatement(sqlMethod.getMethod());
  86. }
  87. @Transactional(rollbackFor = Exception.class)
  88. @Override
  89. public boolean insert(T entity) {
  90. return retBool(baseMapper.insert(entity));
  91. }
  92. @Transactional(rollbackFor = Exception.class)
  93. @Override
  94. public boolean insertAllColumn(T entity) {
  95. return retBool(baseMapper.insertAllColumn(entity));
  96. }
  97. @Transactional(rollbackFor = Exception.class)
  98. @Override
  99. public boolean insertBatch(List<T> entityList) {
  100. return insertBatch(entityList, 30);
  101. }
  102. /**
  103. * 批量插入
  104. *
  105. * @param entityList
  106. * @param batchSize
  107. * @return
  108. */
  109. @Transactional(rollbackFor = Exception.class)
  110. @Override
  111. public boolean insertBatch(List<T> entityList, int batchSize) {
  112. if (CollectionUtils.isEmpty(entityList)) {
  113. throw new IllegalArgumentException("Error: entityList must not be empty");
  114. }
  115. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  116. int size = entityList.size();
  117. String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
  118. for (int i = 0; i < size; i++) {
  119. batchSqlSession.insert(sqlStatement, entityList.get(i));
  120. if (i >= 1 && i % batchSize == 0) {
  121. batchSqlSession.flushStatements();
  122. }
  123. }
  124. batchSqlSession.flushStatements();
  125. } catch (Throwable e) {
  126. throw new MybatisPlusException("Error: Cannot execute insertBatch Method. Cause", e);
  127. }
  128. return true;
  129. }
  130. /**
  131. * <p>
  132. * TableId 注解存在更新记录,否插入一条记录
  133. * </p>
  134. *
  135. * @param entity 实体对象
  136. * @return boolean
  137. */
  138. @Transactional(rollbackFor = Exception.class)
  139. @Override
  140. public boolean insertOrUpdate(T entity) {
  141. if (null != entity) {
  142. Class<?> cls = entity.getClass();
  143. TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
  144. if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
  145. Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
  146. if (StringUtils.checkValNull(idVal)) {
  147. return insert(entity);
  148. } else {
  149. /*
  150. * 更新成功直接返回,失败执行插入逻辑
  151. */
  152. return updateById(entity) || insert(entity);
  153. }
  154. } else {
  155. throw new MybatisPlusException("Error: Can not execute. Could not find @TableId.");
  156. }
  157. }
  158. return false;
  159. }
  160. @Transactional(rollbackFor = Exception.class)
  161. @Override
  162. public boolean insertOrUpdateAllColumn(T entity) {
  163. if (null != entity) {
  164. Class<?> cls = entity.getClass();
  165. TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
  166. if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
  167. Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
  168. if (StringUtils.checkValNull(idVal)) {
  169. return insertAllColumn(entity);
  170. } else {
  171. /*
  172. * 更新成功直接返回,失败执行插入逻辑
  173. */
  174. return updateAllColumnById(entity) || insertAllColumn(entity);
  175. }
  176. } else {
  177. throw new MybatisPlusException("Error: Can not execute. Could not find @TableId.");
  178. }
  179. }
  180. return false;
  181. }
  182. @Transactional(rollbackFor = Exception.class)
  183. @Override
  184. public boolean insertOrUpdateBatch(List<T> entityList) {
  185. return insertOrUpdateBatch(entityList, 30);
  186. }
  187. @Transactional(rollbackFor = Exception.class)
  188. @Override
  189. public boolean insertOrUpdateBatch(List<T> entityList, int batchSize) {
  190. return insertOrUpdateBatch(entityList, batchSize, true);
  191. }
  192. @Transactional(rollbackFor = Exception.class)
  193. @Override
  194. public boolean insertOrUpdateAllColumnBatch(List<T> entityList) {
  195. return insertOrUpdateBatch(entityList, 30, false);
  196. }
  197. @Transactional(rollbackFor = Exception.class)
  198. @Override
  199. public boolean insertOrUpdateAllColumnBatch(List<T> entityList, int batchSize) {
  200. return insertOrUpdateBatch(entityList, batchSize, false);
  201. }
  202. /**
  203. * 批量插入修改
  204. *
  205. * @param entityList 实体对象列表
  206. * @param batchSize 批量刷新个数
  207. * @param selective 是否滤掉空字段
  208. * @return boolean
  209. */
  210. private boolean insertOrUpdateBatch(List<T> entityList, int batchSize, boolean selective) {
  211. if (CollectionUtils.isEmpty(entityList)) {
  212. throw new IllegalArgumentException("Error: entityList must not be empty");
  213. }
  214. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  215. int size = entityList.size();
  216. for (int i = 0; i < size; i++) {
  217. if (selective) {
  218. insertOrUpdate(entityList.get(i));
  219. } else {
  220. insertOrUpdateAllColumn(entityList.get(i));
  221. }
  222. if (i >= 1 && i % batchSize == 0) {
  223. batchSqlSession.flushStatements();
  224. }
  225. }
  226. batchSqlSession.flushStatements();
  227. } catch (Throwable e) {
  228. throw new MybatisPlusException("Error: Cannot execute insertOrUpdateBatch Method. Cause", e);
  229. }
  230. return true;
  231. }
  232. @Transactional(rollbackFor = Exception.class)
  233. @Override
  234. public boolean deleteById(Serializable id) {
  235. return retBool(baseMapper.deleteById(id));
  236. }
  237. @Transactional(rollbackFor = Exception.class)
  238. @Override
  239. public boolean deleteByMap(Map<String, Object> columnMap) {
  240. if (MapUtils.isEmpty(columnMap)) {
  241. throw new MybatisPlusException("deleteByMap columnMap is empty.");
  242. }
  243. return retBool(baseMapper.deleteByMap(columnMap));
  244. }
  245. @Transactional(rollbackFor = Exception.class)
  246. @Override
  247. public boolean delete(Wrapper<T> wrapper) {
  248. return retBool(baseMapper.delete(wrapper));
  249. }
  250. @Transactional(rollbackFor = Exception.class)
  251. @Override
  252. public boolean deleteBatchIds(List<? extends Serializable> idList) {
  253. return retBool(baseMapper.deleteBatchIds(idList));
  254. }
  255. @Transactional(rollbackFor = Exception.class)
  256. @Override
  257. public boolean updateById(T entity) {
  258. return retBool(baseMapper.updateById(entity));
  259. }
  260. @Transactional(rollbackFor = Exception.class)
  261. @Override
  262. public boolean updateAllColumnById(T entity) {
  263. return retBool(baseMapper.updateAllColumnById(entity));
  264. }
  265. @Transactional(rollbackFor = Exception.class)
  266. @Override
  267. public boolean update(T entity, Wrapper<T> wrapper) {
  268. return retBool(baseMapper.update(entity, wrapper));
  269. }
  270. @Transactional(rollbackFor = Exception.class)
  271. @Override
  272. public boolean updateBatchById(List<T> entityList) {
  273. return updateBatchById(entityList, 30);
  274. }
  275. @Transactional(rollbackFor = Exception.class)
  276. @Override
  277. public boolean updateBatchById(List<T> entityList, int batchSize) {
  278. return updateBatchById(entityList, batchSize, true);
  279. }
  280. @Transactional(rollbackFor = Exception.class)
  281. @Override
  282. public boolean updateAllColumnBatchById(List<T> entityList) {
  283. return updateAllColumnBatchById(entityList, 30);
  284. }
  285. @Transactional(rollbackFor = Exception.class)
  286. @Override
  287. public boolean updateAllColumnBatchById(List<T> entityList, int batchSize) {
  288. return updateBatchById(entityList, batchSize, false);
  289. }
  290. /**
  291. * 根据主键ID进行批量修改
  292. *
  293. * @param entityList 实体对象列表
  294. * @param batchSize 批量刷新个数
  295. * @param selective 是否滤掉空字段
  296. * @return boolean
  297. */
  298. private boolean updateBatchById(List<T> entityList, int batchSize, boolean selective) {
  299. if (CollectionUtils.isEmpty(entityList)) {
  300. throw new IllegalArgumentException("Error: entityList must not be empty");
  301. }
  302. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  303. int size = entityList.size();
  304. SqlMethod sqlMethod = selective ? SqlMethod.UPDATE_BY_ID : SqlMethod.UPDATE_ALL_COLUMN_BY_ID;
  305. String sqlStatement = sqlStatement(sqlMethod);
  306. for (int i = 0; i < size; i++) {
  307. MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
  308. param.put("et", entityList.get(i));
  309. batchSqlSession.update(sqlStatement, param);
  310. if (i >= 1 && i % batchSize == 0) {
  311. batchSqlSession.flushStatements();
  312. }
  313. }
  314. batchSqlSession.flushStatements();
  315. } catch (Throwable e) {
  316. throw new MybatisPlusException("Error: Cannot execute updateBatchById Method. Cause", e);
  317. }
  318. return true;
  319. }
  320. @Override
  321. public T selectById(Serializable id) {
  322. return baseMapper.selectById(id);
  323. }
  324. @Override
  325. public List<T> selectBatchIds(List<? extends Serializable> idList) {
  326. return baseMapper.selectBatchIds(idList);
  327. }
  328. @Override
  329. public List<T> selectByMap(Map<String, Object> columnMap) {
  330. return baseMapper.selectByMap(columnMap);
  331. }
  332. @Override
  333. public T selectOne(Wrapper<T> wrapper) {
  334. return SqlHelper.getObject(baseMapper.selectList(wrapper));
  335. }
  336. @Override
  337. public Map<String, Object> selectMap(Wrapper<T> wrapper) {
  338. return SqlHelper.getObject(baseMapper.selectMaps(wrapper));
  339. }
  340. @Override
  341. public Object selectObj(Wrapper<T> wrapper) {
  342. return SqlHelper.getObject(baseMapper.selectObjs(wrapper));
  343. }
  344. @Override
  345. public int selectCount(Wrapper<T> wrapper) {
  346. return SqlHelper.retCount(baseMapper.selectCount(wrapper));
  347. }
  348. @Override
  349. public List<T> selectList(Wrapper<T> wrapper) {
  350. return baseMapper.selectList(wrapper);
  351. }
  352. @Override
  353. public Page<T> selectPage(Page<T> page) {
  354. return selectPage(page, Condition.EMPTY);
  355. }
  356. @Override
  357. public List<Map<String, Object>> selectMaps(Wrapper<T> wrapper) {
  358. return baseMapper.selectMaps(wrapper);
  359. }
  360. @Override
  361. public List<Object> selectObjs(Wrapper<T> wrapper) {
  362. return baseMapper.selectObjs(wrapper);
  363. }
  364. @Override
  365. public Page<Map<String, Object>> selectMapsPage(Page page, Wrapper<T> wrapper) {
  366. SqlHelper.fillWrapper(page, wrapper);
  367. page.setRecords(baseMapper.selectMapsPage(page, wrapper));
  368. return page;
  369. }
  370. @Override
  371. public Page<T> selectPage(Page<T> page, Wrapper<T> wrapper) {
  372. SqlHelper.fillWrapper(page, wrapper);
  373. page.setRecords(baseMapper.selectPage(page, wrapper));
  374. return page;
  375. }
  376. }