使用泛型、设计模式和mybatis-plus封装简单CURD的操作

使用泛型、设计模式和mybatis-plus封装简单CURD的操作

使用泛型、模板模式、默认实现类、本地缓存等设计思想在mybatis-plus肩膀上实现简单crud的代码复用。

1、规约

  • 表字段名规约:id/create_time/update_time/is_deleted
  • 公共字段类实体:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

import java.util.Date;

@Data
public class BaseEntity {

	@TableId(type = IdType.AUTO)
	private Integer id;
	private Date createTime;
	private Date updateTime;
	private String isDeleted;
}

2、实现

UML图如下:
在这里插入图片描述

1. 基础crud接口

public interface BaseService<T> {

	int insert(T t) throws NoSuchMethodException;
    
    int update(T t) throws NoSuchMethodException;

	T selectById(Integer id) throws NoSuchMethodException;

	/**
	 * 逻辑删除
	 */
	int deleteLogic(Integer id) throws NoSuchMethodException;

	/**
	 * 物理删除
	 */
	int delete(Integer id) throws NoSuchMethodException;

2. 基础实现类,实现基础CRUD接口

public class BaseServiceImpl<T> implements BaseService<T> {

	@Override
	int insert(T t) throws NoSuchMethodException{
        throw new NoSuchMethodException();
    }
    
    @Override
    int update(T t) throws NoSuchMethodException{
        throw new NoSuchMethodException();
    }
    
	@Override
	public T selectById(Integer id) throws NoSuchMethodException {
		throw new NoSuchMethodException();
	}

	@Override
	public int deleteLogic(Integer id) throws NoSuchMethodException {
		throw new NoSuchMethodException();
	}

	@Override
	public int delete(Integer id) throws NoSuchMethodException {
		throw new NoSuchMethodException();
	}

	protected void setInsertTimeParams(T t) {
		if (t instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) t;
			Date now = new Date();
			baseEntity.setCreateTime(now);
			baseEntity.setUpdateTime(now);
		}
	}

	protected void setUpdateTimeParams(T t) {
		if (t instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) t;
			baseEntity.setUpdateTime(new Date());
		}
	}
}

3. 抽象类,继承基础实现类

public abstract class AbstractServiceImpl<T> extends BaseServiceImpl<T> {

	private static Map<String, String> mapperNameCache = new HashMap<>();

	@Resource
	private Map<String, BaseMapper<T>> baseMapperMap;

	// 设置新增记录的业务信息方法
	protected abstract void setInsertParams(T t);

	// 设置修改记录的业务信息方法
	protected abstract void setUpdateParams(T t);

	@Override
	public int insert(T t) throws NoSuchMethodException {
		BaseMapper<T> baseMapper = getBaseMapper();
		if (Objects.isNull(t)) {
			throw new BizException("新增或修改的信息不能为空!");
		}
		if (!(t instanceof BaseEntity)) {
			throw new NoSuchMethodException();
		}
		BaseEntity baseEntity = (BaseEntity) t;
        // 新增时,设置业务信息
        setInsertParams(t);
        setInsertTimeParams(t);
        return baseMapper.insert(t);
		
	}

    @Override
    public int update(T t) throws NoSuchMethodException {
            BaseMapper<T> baseMapper = getBaseMapper();
            if (Objects.isNull(t)) {
                throw new BizException("新增或修改的信息不能为空!");
            }
            if (!(t instanceof BaseEntity)) {
                throw new NoSuchMethodException();
            }
            BaseEntity baseEntity = (BaseEntity) t;
            if (Objects.isNull(baseEntity.getId())) {
            	throw new BizException("记录id不能为空!");
            }
            T entityFromBb = selectById(baseEntity.getId());
            if (Objects.isNull(entityFromBb)) {
                throw new BizException("该记录已删除,修改失败!");
            }
            // 修改时,设置业务
            setUpdateParams(t);
            setUpdateTimeParams(t);
            BeanUtil.copyPropertiesIgnoreNull(t, entityFromBb);
            return baseMapper.updateById(entityFromBb);
        }

	@Override
	public T selectById(Integer id) {
		BaseMapper<T> baseMapper = getBaseMapper();
		QueryWrapper<T> wrapper = new QueryWrapper<T>()
				.eq("is_deleted", WhetherEnum.NO.getCode())
				.eq("id", id);
		return baseMapper.selectOne(wrapper);
	}

	@Override
	public int deleteLogic(Integer id) throws NoSuchMethodException {
		BaseMapper<T> baseMapper = getBaseMapper();
		if (Objects.isNull(id)) {
			throw new BizException("删除传入的id不能为空!");
		}
		T t = selectById(id);
		if (!(t instanceof BaseEntity)) {
			throw new NoSuchMethodException();
		}
		BaseEntity entity = (BaseEntity) t;
		entity.setIsDeleted(WhetherEnum.YES.getCode());
		setUpdateTimeParams(t);
		return baseMapper.updateById(t);
	}

	@Override
	public int delete(Integer id) {
		BaseMapper<T> baseMapper = getBaseMapper();
		return baseMapper.deleteById(id);
	}

	/**
	 * 获取mapper对象(使用缓存)
	 *
	 * @return
	 */
	private BaseMapper<T> getBaseMapper() {
		// 使用泛型工具类获取T的具体类型
		String className = GenericUtil.getGenericType(this.getClass());
		String classNameGet = mapperNameCache.get(className);
		if (Objects.nonNull(classNameGet)) {
			return baseMapperMap.get(classNameGet);
		}
		int index = className.lastIndexOf(".") + 1;
		String simpleName = className.substring(index);
		StringBuilder mapperNameAppender = new StringBuilder();
		if (simpleName.length() == 1) {
			mapperNameAppender.append(simpleName.toLowerCase());
		} else {
			mapperNameAppender.append(simpleName.substring(0, 1).toLowerCase());
			mapperNameAppender.append(simpleName.substring(1));
		}
		mapperNameAppender.append("Mapper");
		String mapperName = mapperNameAppender.toString();
		mapperNameCache.put(className, mapperName);
		return baseMapperMap.get(mapperName);
	}

}

4. 默认实现类,继承抽象类

public class DefaultServiceImpl<T> extends AbstractServiceImpl<T> {
	@Override
	protected void setInsertParams(T t) {

	}

	@Override
	protected void setUpdateParams(T t) {

	}

}

5. 业务实现类,继承默认实现类,选择性重写父类方法

@Service
public class BaseInfoServiceImpl extends DefaultServiceImpl<BaseInfo> implements BaseInfoService {

	@Override
	protected void setInsertParams(BaseInfo baseInfo) {
		// 生成id
		baseInfo.setId(UUIDUtil.generate());
	}
}

6. 泛型工具类

/**
 * 泛型相关工具
 */
public class GenericUtil {

	private GenericUtil() {}

	/**
	 * 获取泛型的具体类型
	 *
	 * @param clazz
	 * @return
	 */
	public static String getGenericType(Class<?> clazz) {
		Type type = clazz.getGenericSuperclass();
		if (!(type instanceof ParameterizedType)) {
			throw new BizException("无法获取mapper,请检查是否提供泛型!");
		}

		// 强制类型转换
		ParameterizedType pType = (ParameterizedType) type;
		// 取得泛型类型的泛型参数
		return pType.getActualTypeArguments()[0].getTypeName();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值