BaseService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package com.coffee.common.crud;
  2. import cn.dev33.satoken.session.SaSession;
  3. import cn.dev33.satoken.stp.StpUtil;
  4. import cn.hutool.core.collection.CollectionUtil;
  5. import cn.hutool.core.util.ObjectUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import cn.hutool.db.sql.Direction;
  8. import cn.hutool.db.sql.Order;
  9. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  10. import com.baomidou.mybatisplus.core.enums.SqlMethod;
  11. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  12. import com.baomidou.mybatisplus.core.metadata.IPage;
  13. import com.baomidou.mybatisplus.core.metadata.TableInfo;
  14. import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
  15. import com.baomidou.mybatisplus.core.toolkit.Assert;
  16. import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  17. import com.baomidou.mybatisplus.core.toolkit.Constants;
  18. import com.baomidou.mybatisplus.core.toolkit.StringUtils;
  19. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  20. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  21. import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
  22. import com.coffee.common.bo.LoginUser;
  23. import com.coffee.common.entity.QueryParamEntity;
  24. import com.coffee.common.entity.param.Term;
  25. import com.coffee.common.exception.CustomException;
  26. import org.apache.ibatis.binding.MapperMethod;
  27. import org.springframework.data.domain.PageRequest;
  28. import org.springframework.jdbc.BadSqlGrammarException;
  29. import org.springframework.transaction.annotation.Transactional;
  30. import java.io.Serializable;
  31. import java.sql.SQLSyntaxErrorException;
  32. import java.util.Collection;
  33. import java.util.List;
  34. import java.util.Objects;
  35. import java.util.Set;
  36. /**
  37. * @Author lifang
  38. * @Date 10:02 2022/3/14
  39. * @Description PK为主键类型
  40. * @Param
  41. * @return
  42. **/
  43. public abstract class BaseService<M extends BaseMapper<E>, E,PK extends Serializable> extends ServiceImpl<M, E> {
  44. /**
  45. * 当使用缓存时使用该属性表示缓存名称
  46. **/
  47. private final String cacheBucket;
  48. public String getCacheBucketName(){
  49. return cacheBucket;
  50. }
  51. public BaseService() {
  52. this.cacheBucket = this.getClass().getSimpleName();
  53. }
  54. public BaseService(String cacheBucket) {
  55. this.cacheBucket = cacheBucket;
  56. }
  57. @Override
  58. @Transactional(rollbackFor = Exception.class)
  59. public boolean saveBatch(Collection<E> entityList, int batchSize) {
  60. entityList.forEach(this::validateBeforeSave);
  61. if (super.saveBatch(entityList, batchSize)) {
  62. entityList.forEach(this::postSave);
  63. return true;
  64. }
  65. return false;
  66. }
  67. @Override
  68. @Transactional(rollbackFor = Exception.class)
  69. public boolean save(E entity) {
  70. if (super.save(entity)) {
  71. postSave(entity);
  72. return true;
  73. }
  74. return false;
  75. }
  76. /**
  77. * @Author lifang
  78. * @Date 10:05 2022/3/14
  79. * @Description 在使用时请尽量将update操作和save操作分开
  80. * @Param [entity]
  81. * @return boolean
  82. **/
  83. @Override
  84. @Deprecated
  85. @Transactional(rollbackFor = Exception.class)
  86. public boolean saveOrUpdate(E entity) {
  87. if (null != entity) {
  88. TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
  89. Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
  90. String keyProperty = tableInfo.getKeyProperty();
  91. Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
  92. Object idVal = tableInfo.getPropertyValue(entity, tableInfo.getKeyProperty());
  93. if (StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal))) {
  94. if(save(entity)){
  95. postSave(entity);
  96. return true;
  97. }
  98. return false;
  99. }else {
  100. if(updateById(entity)){
  101. postUpdate(entity);
  102. return true;
  103. }
  104. return false;
  105. }
  106. }
  107. return false;
  108. }
  109. /**
  110. * @Author lifang
  111. * @Date 10:05 2022/3/14
  112. * @Description 在使用时请尽量将update操作和save操作分开
  113. * @Param [entity]
  114. * @return boolean
  115. **/
  116. @Override
  117. @Transactional(rollbackFor = Exception.class)
  118. @Deprecated
  119. public boolean saveOrUpdateBatch(Collection<E> entityList, int batchSize) {
  120. TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
  121. Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
  122. String keyProperty = tableInfo.getKeyProperty();
  123. Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
  124. return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
  125. Object idVal = tableInfo.getPropertyValue(entity, keyProperty);
  126. validateBeforeSave(entity);
  127. return StringUtils.checkValNull(idVal)
  128. || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
  129. }, (sqlSession, entity) -> {
  130. MapperMethod.ParamMap<E> param = new MapperMethod.ParamMap<>();
  131. validateBeforeUpdate(entity);
  132. param.put(Constants.ENTITY, entity);
  133. if (sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param)==0) {
  134. postUpdate(entity);
  135. }
  136. });
  137. }
  138. @Override
  139. public boolean removeById(Serializable id) {
  140. validateBeforeDelete((PK) id);
  141. if (super.removeById(id)) {
  142. postDelete((PK) id);
  143. return true;
  144. }
  145. return false;
  146. }
  147. @Override
  148. public boolean removeByIds(Collection<?> list) {
  149. list.stream().map(id->(PK)id).forEach(this::validateBeforeDelete);
  150. if (super.removeByIds(list)) {
  151. list.stream().map(id->(PK)id).forEach(this::postDelete);
  152. return true;
  153. }
  154. return false;
  155. }
  156. @Override
  157. public boolean removeById(Serializable id, boolean useFill) {
  158. this.validateBeforeDelete((PK) id);
  159. if (super.removeById(id, useFill)) {
  160. postDelete((PK) id);
  161. return true;
  162. }
  163. return false;
  164. }
  165. @Override
  166. public boolean removeBatchByIds(Collection<?> list, int batchSize) {
  167. list.stream().map(id->(PK)id).forEach(this::validateBeforeDelete);
  168. if (super.removeBatchByIds(list, batchSize)) {
  169. list.stream().map(id->(PK)id).forEach(this::postDelete);
  170. return true;
  171. }
  172. return false;
  173. }
  174. @Override
  175. public boolean removeBatchByIds(Collection<?> list, int batchSize, boolean useFill) {
  176. list.stream().map(id->(PK)id).forEach(this::validateBeforeDelete);
  177. if (super.removeBatchByIds(list, batchSize, useFill)) {
  178. list.stream().map(id->(PK)id).forEach(this::postDelete);
  179. return true;
  180. }
  181. return false;
  182. }
  183. @Override
  184. @Transactional(rollbackFor = Exception.class)
  185. public boolean updateById(E entity) {
  186. validateBeforeUpdate(entity);
  187. if (super.updateById(entity)) {
  188. postUpdate(entity);
  189. return true;
  190. }
  191. return false;
  192. }
  193. @Override
  194. @Transactional(rollbackFor = Exception.class)
  195. public boolean updateBatchById(Collection<E> entityList) {
  196. entityList.forEach(this::validateBeforeUpdate);
  197. if (super.updateBatchById(entityList)) {
  198. entityList.forEach(this::postUpdate);
  199. return true;
  200. }
  201. return false;
  202. }
  203. public IPage<E> list(QueryParamEntity<E> param) {
  204. //是否为分页查询
  205. if(ObjectUtil.isNotNull(param.getPage())){
  206. QueryWrapper<E> wrapper = build(param);
  207. Page<E> page = param.getPage();
  208. // page.setCurrent(page.getCurrent()>0?page.getCurrent()-1:0);
  209. return this.page(page,wrapper);
  210. }else {
  211. try {
  212. List<E> list = list(build(param));
  213. Page<E> page = Page.of(0,1,CollectionUtil.isEmpty(list)?0:list.size());
  214. page.setRecords(list);
  215. return page;
  216. }catch (Exception e){
  217. if(e instanceof BadSqlGrammarException){
  218. throw new CustomException(e.getCause().getMessage());
  219. }
  220. }
  221. return new Page<>();
  222. }
  223. }
  224. public long count(QueryParamEntity<E> param) {
  225. return this.count(build(param));
  226. }
  227. public QueryWrapper<E> build(QueryParamEntity<?> param){
  228. QueryWrapper<E> queryWrapper = new QueryWrapper<>();
  229. Set<String> includes = param.getIncludes();
  230. Set<Term> wheres = param.getWheres();
  231. Set<Order> orders = param.getOrders();
  232. if(CollectionUtil.isNotEmpty(includes)){
  233. queryWrapper.select(includes.toArray(new String[includes.size()+1]));
  234. }
  235. if (CollectionUtil.isNotEmpty(wheres)) {
  236. wheres.forEach(term -> term.getType().build(queryWrapper,term));
  237. }
  238. if(CollectionUtil.isNotEmpty(orders)){
  239. orders.forEach(order -> {
  240. String field = order.getField();
  241. String column = StrUtil.toUnderlineCase(field).toLowerCase();
  242. Direction direction = order.getDirection();
  243. if(Direction.ASC==direction){
  244. queryWrapper.orderByAsc(column);
  245. }else {
  246. queryWrapper.orderByDesc(column);
  247. }
  248. });
  249. }
  250. // else {
  251. // queryWrapper.orderByDesc("create_time");
  252. // }
  253. if(StrUtil.isNotEmpty(param.getTenantId())&&!StrUtil.isNullOrUndefined(param.getTenantId())){
  254. LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(com.coffee.common.Constants.LOGIN_USER_KEY);
  255. //是否为系统用户
  256. if(loginUser!=null&&Boolean.TRUE.equals(loginUser.getIsSys())){
  257. queryWrapper.eq("tenant_id",param.getTenantId());
  258. }
  259. }
  260. return queryWrapper;
  261. }
  262. /**
  263. * 保存成功后操作
  264. */
  265. public void postSave(E entity ){
  266. }
  267. /**
  268. * 更新成功后操作
  269. */
  270. public void postUpdate(E entity){
  271. }
  272. /**
  273. * 删除成功后操作
  274. */
  275. public void postDelete(PK id){
  276. }
  277. /**
  278. * @Author lifang
  279. * @Date 10:00 2022/3/14
  280. * @Description 保存数据前进行验证
  281. * @Param [entity]
  282. * @return void
  283. **/
  284. public abstract void validateBeforeSave(E entity) ;
  285. /**
  286. * @Author lifang
  287. * @Date 10:00 2022/3/14
  288. * @Description 更新数据前进行验证
  289. * @Param [entity]
  290. * @return void
  291. **/
  292. public abstract void validateBeforeUpdate(E entity) ;
  293. /**
  294. * @Author lifang
  295. * @Date 10:02 2022/3/14
  296. * @Description 删除数据前进行验证
  297. * @Param [id]
  298. * @return void
  299. **/
  300. public abstract void validateBeforeDelete(PK id) ;
  301. }