ServiceImpl.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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
  88. public boolean insert(T entity) {
  89. return retBool(baseMapper.insert(entity));
  90. }
  91. @Transactional
  92. public boolean insertAllColumn(T entity) {
  93. return retBool(baseMapper.insertAllColumn(entity));
  94. }
  95. @Transactional
  96. public boolean insertBatch(List<T> entityList) {
  97. return insertBatch(entityList, 30);
  98. }
  99. /**
  100. * 批量插入
  101. *
  102. * @param entityList
  103. * @param batchSize
  104. * @return
  105. */
  106. @Transactional
  107. public boolean insertBatch(List<T> entityList, int batchSize) {
  108. if (CollectionUtils.isEmpty(entityList)) {
  109. throw new IllegalArgumentException("Error: entityList must not be empty");
  110. }
  111. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  112. int size = entityList.size();
  113. String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE);
  114. for (int i = 0; i < size; i++) {
  115. batchSqlSession.insert(sqlStatement, entityList.get(i));
  116. if (i >= 1 && i % batchSize == 0) {
  117. batchSqlSession.flushStatements();
  118. }
  119. }
  120. batchSqlSession.flushStatements();
  121. } catch (Throwable e) {
  122. throw new MybatisPlusException("Error: Cannot execute insertBatch Method. Cause", e);
  123. }
  124. return true;
  125. }
  126. /**
  127. * <p>
  128. * TableId 注解存在更新记录,否插入一条记录
  129. * </p>
  130. *
  131. * @param entity 实体对象
  132. * @return boolean
  133. */
  134. @Transactional
  135. public boolean insertOrUpdate(T entity) {
  136. if (null != entity) {
  137. Class<?> cls = entity.getClass();
  138. TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
  139. if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
  140. Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
  141. if (StringUtils.checkValNull(idVal)) {
  142. return insert(entity);
  143. } else {
  144. /*
  145. * 更新成功直接返回,失败执行插入逻辑
  146. */
  147. return updateById(entity) || insert(entity);
  148. }
  149. } else {
  150. throw new MybatisPlusException("Error: Can not execute. Could not find @TableId.");
  151. }
  152. }
  153. return false;
  154. }
  155. @Transactional
  156. public boolean insertOrUpdateAllColumn(T entity) {
  157. if (null != entity) {
  158. Class<?> cls = entity.getClass();
  159. TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
  160. if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
  161. Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
  162. if (StringUtils.checkValNull(idVal)) {
  163. return insertAllColumn(entity);
  164. } else {
  165. /*
  166. * 更新成功直接返回,失败执行插入逻辑
  167. */
  168. return updateAllColumnById(entity) || insertAllColumn(entity);
  169. }
  170. } else {
  171. throw new MybatisPlusException("Error: Can not execute. Could not find @TableId.");
  172. }
  173. }
  174. return false;
  175. }
  176. @Transactional
  177. public boolean insertOrUpdateBatch(List<T> entityList) {
  178. return insertOrUpdateBatch(entityList, 30);
  179. }
  180. @Transactional
  181. public boolean insertOrUpdateBatch(List<T> entityList, int batchSize) {
  182. return insertOrUpdateBatch(entityList, batchSize, true);
  183. }
  184. @Transactional
  185. public boolean insertOrUpdateAllColumnBatch(List<T> entityList) {
  186. return insertOrUpdateBatch(entityList, 30, false);
  187. }
  188. @Transactional
  189. public boolean insertOrUpdateAllColumnBatch(List<T> entityList, int batchSize) {
  190. return insertOrUpdateBatch(entityList, batchSize, false);
  191. }
  192. /**
  193. * 批量插入修改
  194. *
  195. * @param entityList 实体对象列表
  196. * @param batchSize 批量刷新个数
  197. * @param selective 是否滤掉空字段
  198. * @return boolean
  199. */
  200. private boolean insertOrUpdateBatch(List<T> entityList, int batchSize, boolean selective) {
  201. if (CollectionUtils.isEmpty(entityList)) {
  202. throw new IllegalArgumentException("Error: entityList must not be empty");
  203. }
  204. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  205. int size = entityList.size();
  206. for (int i = 0; i < size; i++) {
  207. if (selective) {
  208. insertOrUpdate(entityList.get(i));
  209. } else {
  210. insertOrUpdateAllColumn(entityList.get(i));
  211. }
  212. if (i >= 1 && i % batchSize == 0) {
  213. batchSqlSession.flushStatements();
  214. }
  215. }
  216. batchSqlSession.flushStatements();
  217. } catch (Throwable e) {
  218. throw new MybatisPlusException("Error: Cannot execute insertOrUpdateBatch Method. Cause", e);
  219. }
  220. return true;
  221. }
  222. @Transactional
  223. public boolean deleteById(Serializable id) {
  224. return retBool(baseMapper.deleteById(id));
  225. }
  226. @Transactional
  227. public boolean deleteByMap(Map<String, Object> columnMap) {
  228. if (MapUtils.isEmpty(columnMap)) {
  229. throw new MybatisPlusException("deleteByMap columnMap is empty.");
  230. }
  231. return retBool(baseMapper.deleteByMap(columnMap));
  232. }
  233. @Transactional
  234. public boolean delete(Wrapper<T> wrapper) {
  235. return retBool(baseMapper.delete(wrapper));
  236. }
  237. @Transactional
  238. public boolean deleteBatchIds(List<? extends Serializable> idList) {
  239. return retBool(baseMapper.deleteBatchIds(idList));
  240. }
  241. @Transactional
  242. public boolean updateById(T entity) {
  243. return retBool(baseMapper.updateById(entity));
  244. }
  245. @Transactional
  246. public boolean updateAllColumnById(T entity) {
  247. return retBool(baseMapper.updateAllColumnById(entity));
  248. }
  249. @Transactional
  250. public boolean update(T entity, Wrapper<T> wrapper) {
  251. return retBool(baseMapper.update(entity, wrapper));
  252. }
  253. @Transactional
  254. public boolean updateBatchById(List<T> entityList) {
  255. return updateBatchById(entityList, 30);
  256. }
  257. @Transactional
  258. public boolean updateBatchById(List<T> entityList, int batchSize) {
  259. return updateBatchById(entityList, batchSize, true);
  260. }
  261. @Transactional
  262. public boolean updateAllColumnBatchById(List<T> entityList) {
  263. return updateAllColumnBatchById(entityList, 30);
  264. }
  265. @Transactional
  266. public boolean updateAllColumnBatchById(List<T> entityList, int batchSize) {
  267. return updateBatchById(entityList, batchSize, false);
  268. }
  269. /**
  270. * 根据主键ID进行批量修改
  271. *
  272. * @param entityList 实体对象列表
  273. * @param batchSize 批量刷新个数
  274. * @param selective 是否滤掉空字段
  275. * @return boolean
  276. */
  277. private boolean updateBatchById(List<T> entityList, int batchSize, boolean selective) {
  278. if (CollectionUtils.isEmpty(entityList)) {
  279. throw new IllegalArgumentException("Error: entityList must not be empty");
  280. }
  281. try (SqlSession batchSqlSession = sqlSessionBatch()) {
  282. int size = entityList.size();
  283. SqlMethod sqlMethod = selective ? SqlMethod.UPDATE_BY_ID : SqlMethod.UPDATE_ALL_COLUMN_BY_ID;
  284. String sqlStatement = sqlStatement(sqlMethod);
  285. for (int i = 0; i < size; i++) {
  286. MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
  287. param.put("et", entityList.get(i));
  288. batchSqlSession.update(sqlStatement, param);
  289. if (i >= 1 && i % batchSize == 0) {
  290. batchSqlSession.flushStatements();
  291. }
  292. }
  293. batchSqlSession.flushStatements();
  294. } catch (Throwable e) {
  295. throw new MybatisPlusException("Error: Cannot execute updateBatchById Method. Cause", e);
  296. }
  297. return true;
  298. }
  299. public T selectById(Serializable id) {
  300. return baseMapper.selectById(id);
  301. }
  302. public List<T> selectBatchIds(List<? extends Serializable> idList) {
  303. return baseMapper.selectBatchIds(idList);
  304. }
  305. public List<T> selectByMap(Map<String, Object> columnMap) {
  306. return baseMapper.selectByMap(columnMap);
  307. }
  308. public T selectOne(Wrapper<T> wrapper) {
  309. return SqlHelper.getObject(baseMapper.selectList(wrapper));
  310. }
  311. public Map<String, Object> selectMap(Wrapper<T> wrapper) {
  312. return SqlHelper.getObject(baseMapper.selectMaps(wrapper));
  313. }
  314. public Object selectObj(Wrapper<T> wrapper) {
  315. return SqlHelper.getObject(baseMapper.selectObjs(wrapper));
  316. }
  317. public int selectCount(Wrapper<T> wrapper) {
  318. return SqlHelper.retCount(baseMapper.selectCount(wrapper));
  319. }
  320. public List<T> selectList(Wrapper<T> wrapper) {
  321. return baseMapper.selectList(wrapper);
  322. }
  323. @SuppressWarnings("unchecked")
  324. public Page<T> selectPage(Page<T> page) {
  325. return selectPage(page, Condition.EMPTY);
  326. }
  327. public List<Map<String, Object>> selectMaps(Wrapper<T> wrapper) {
  328. return baseMapper.selectMaps(wrapper);
  329. }
  330. public List<Object> selectObjs(Wrapper<T> wrapper) {
  331. return baseMapper.selectObjs(wrapper);
  332. }
  333. @SuppressWarnings({"rawtypes", "unchecked"})
  334. public Page<Map<String, Object>> selectMapsPage(Page page, Wrapper<T> wrapper) {
  335. SqlHelper.fillWrapper(page, wrapper);
  336. page.setRecords(baseMapper.selectMapsPage(page, wrapper));
  337. return page;
  338. }
  339. public Page<T> selectPage(Page<T> page, Wrapper<T> wrapper) {
  340. SqlHelper.fillWrapper(page, wrapper);
  341. page.setRecords(baseMapper.selectPage(page, wrapper));
  342. return page;
  343. }
  344. }