/** * Copyright (c) 2018 人人开源 All rights reserved. * * https://www.renren.io * * 版权所有,侵权必究! */ package com.example.client.service; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.enums.SqlMethod; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import com.example.server.entity.BaseEntity; import com.example.client.entity.PlatformEntity; import com.example.client.entity.RenException; import org.apache.ibatis.binding.MapperMethod; import org.apache.ibatis.session.SqlSession; import org.mybatis.spring.SqlSessionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 基础服务接口,所有Service接口都要继承 * * @author hehz */ public abstract class BaseService, Entity extends BaseEntity> { @Autowired protected Dao baseDao; private Class getEntityClass() { Class entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[1]; return entityClass; } public Entity get(Long id) { Entity entity = baseDao.selectById(id); return entity; } @Transactional(rollbackFor = Exception.class) public void insert(Entity entity) { baseDao.insert(entity); } @Transactional(rollbackFor = Exception.class) public void update(Entity entity) { baseDao.updateById(entity); } /** * 根据 whereEntity 条件,更新记录 */ @Transactional(rollbackFor = Exception.class) public void update(Entity entity, Wrapper updateWrapper) { baseDao.update(entity, updateWrapper); } @Transactional(rollbackFor = Exception.class) public void deleteLogic(Serializable id) { Entity entity = baseDao.selectById(id); if (entity != null) { if (entity instanceof PlatformEntity) { ((PlatformEntity) entity).setDelete(true); baseDao.updateById(entity); } else { baseDao.deleteById(id); // 处理附件,逻辑删除的不处理附件 } } } @Transactional(rollbackFor = Exception.class) public void deleteLogic(Long[] ids) { for (Long id : ids) { this.deleteLogic(id); } } @Transactional(rollbackFor = Exception.class) public void deleteLogic(Collection idList) { for (Serializable id : idList) { this.deleteLogic(id); } } @Transactional(rollbackFor = Exception.class) public void deleteLogic(List entities) { for (Entity entity : entities) { this.deleteLogic(entity.getId()); } } /** *

* 插入(批量),该方法不支持 Oracle、SQL Server *

* * @param entityList * 实体对象集合 * @param batchSize * 插入批次数量 */ @Transactional(rollbackFor = Exception.class) public boolean insertBatch(Collection entityList, int batchSize) { SqlSession session = sqlSessionBatch(); int i = 0; String sqlStatement = sqlStatement(SqlMethod.INSERT_ONE); try { for (Entity entity : entityList) { session.insert(sqlStatement, entity); if (i >= 1 && i % batchSize == 0) { session.flushStatements(); } i++; } session.flushStatements(); } finally { closeSqlSession(session); } return true; } /** *

* 根据ID 批量更新 *

* * @param entityList * 实体对象集合 * @param batchSize * 更新批次数量 */ @Transactional(rollbackFor = Exception.class) public boolean updateBatch(Collection entityList, int batchSize) { if (CollectionUtils.isEmpty(entityList)) { throw new IllegalArgumentException("Error: entityList must not be empty"); } SqlSession session = sqlSessionBatch(); int i = 0; String sqlStatement = sqlStatement(SqlMethod.UPDATE_BY_ID); try { for (Entity entity : entityList) { MapperMethod.ParamMap param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); session.update(sqlStatement, param); if (i >= 1 && i % batchSize == 0) { session.flushStatements(); } i++; } session.flushStatements(); } finally { closeSqlSession(session); } return true; } /** * 保存关联关系 * * @param relatedField1Name * 被关联的,以它为主 * @param relatedField1Value * @param relatedField2Name * @param datas */ public void saveRelatedDatas(String relatedField1Name, Long relatedField1Value, String relatedField2Name, List datas) { List all = baseDao.selectList(new QueryWrapper().eq(relatedField1Name, relatedField1Value)); Map map = new HashMap<>(); relatedField2Name = StrUtil.toCamelCase(relatedField2Name);// 转成驼峰 for (Entity entity : all) { map.put(ReflectUtil.getFieldValue(entity, relatedField2Name).toString(), entity); } for (Entity data : datas) { String key = ReflectUtil.getFieldValue(data, relatedField2Name).toString(); Entity db = map.get(key); if (db != null) {// 原来存在 if (data instanceof PlatformEntity) { if (((PlatformEntity) db).isDelete()) { ((PlatformEntity) db).setDelete(false); baseDao.updateById(db); } } map.remove(key); } else { baseDao.insert(data); } } for (Entity entity : map.values()) { if (entity instanceof PlatformEntity) { ((PlatformEntity) entity).setDelete(true); baseDao.updateById(entity); } else { throw new RenException("业务模型异常!"); } } } /** *

* 判断数据库操作是否成功 *

*

* 注意!! 该方法为 Integer 判断,不可传入 int 基本类型 *

* * @param result * 数据库操作返回影响条数 * @return boolean */ protected static boolean retBool(Integer result) { return SqlHelper.retBool(result); } /** * 获取SqlStatement * * @param sqlMethod * @return */ protected String sqlStatement(SqlMethod sqlMethod) { return SqlHelper.table(currentModelClass()).getSqlStatement(sqlMethod.getMethod()); } protected Class currentModelClass() { return (Class) ReflectionKit.getSuperClassGenericType(getClass(), 1); } /** *

* 批量操作 SqlSession *

*/ protected SqlSession sqlSessionBatch() { return SqlHelper.sqlSessionBatch(currentModelClass()); } /** * 释放sqlSession * * @param sqlSession * session */ protected void closeSqlSession(SqlSession sqlSession) { SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(currentModelClass())); } }