package com.kidgrow.common.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kidgrow.common.exception.IdempotencyException;
import com.kidgrow.common.exception.LockException;
import com.kidgrow.common.lock.DistributedLock;
import com.kidgrow.common.service.ISuperService;
import java.io.Serializable;
import java.util.Objects;
/**
* 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020
*
* @Description: Service实现父类
* @Project:
* @CreateDate: Created in 2020/2/3 16:01
* @Author: liuke
*/
public class SuperServiceImpl, T> extends ServiceImpl implements ISuperService {
/**
* 幂等性新增记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
@Override
public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg) {
if (lock == null) {
throw new LockException("DistributedLock is null");
}
if (StrUtil.isEmpty(lockKey)) {
throw new LockException("lockKey is null");
}
try {
//加锁
boolean isLock = lock.lock(lockKey);
if (isLock) {
//判断记录是否已存在
int count = super.count(countWrapper);
if (count == 0) {
return super.save(entity);
} else {
if (StrUtil.isEmpty(msg)) {
msg = "已存在";
}
throw new IdempotencyException(msg);
}
} else {
throw new LockException("锁等待超时");
}
} finally {
lock.releaseLock(lockKey);
}
}
/**
* 幂等性新增记录
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
@Override
public boolean saveIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) {
return saveIdempotency(entity, lock, lockKey, countWrapper, null);
}
/**
* 幂等性新增或更新记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveOrUpdateIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @param msg 对象已存在提示信息
* @return
*/
@Override
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper, String msg) {
if (null != entity) {
Class> cls = entity.getClass();
TableInfo tableInfo = TableInfoHelper.getTableInfo(cls);
if (null != tableInfo && StringUtils.isNotEmpty(tableInfo.getKeyProperty())) {
Object idVal = ReflectionKit.getMethodValue(cls, entity, tableInfo.getKeyProperty());
if (StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal))) {
if (StrUtil.isEmpty(msg)) {
msg = "已存在";
}
return this.saveIdempotency(entity, lock, lockKey, countWrapper, msg);
} else {
return updateById(entity);
}
} else {
throw ExceptionUtils.mpe("Error: Can not execute. Could not find @TableId.");
}
}
return false;
}
/**
* 幂等性新增或更新记录
* 例子如下:
* String username = sysUser.getUsername();
* boolean result = super.saveOrUpdateIdempotency(sysUser, lock
* , LOCK_KEY_USERNAME+username
* , new QueryWrapper().eq("username", username));
*
* @param entity 实体对象
* @param lock 锁实例
* @param lockKey 锁的key
* @param countWrapper 判断是否存在的条件
* @return
*/
@Override
public boolean saveOrUpdateIdempotency(T entity, DistributedLock lock, String lockKey, Wrapper countWrapper) {
return this.saveOrUpdateIdempotency(entity, lock, lockKey, countWrapper, null);
}
}