MybatisPlus 根据实体类获取对应的Mapper
2024-06-18 本文已影响0人
饱饱抓住了灵感
一、思路
MybatisPlus没有直接提供根据实体类获取Mapper的方法, 因此我们考虑手动构造.
一个思路是在Bean初始化时构建一个Map关系, 这里主要用到BeanPostProcessor.
BeanPostProcessor是Spring IOC容器给我们提供的一个扩展接口, 我们可以通过实现它对Spring管理的bean进行再加工。
接口声明如下:
public interface BeanPostProcessor {
// bean初始化方法调用前被调用
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
// bean初始化方法调用后被调用
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
说明:
- postProcessBeforeInitialization方法会在任何bean初始化回调(如InitializingBean的afterPropertiesSet方法或者自定义的init-method)之前被调用。也就是说,这个方法会在bean的属性已经设置完毕,但还未进行初始化时被调用。
- postProcessAfterInitialization方法在任何bean初始化回调(比如InitializingBean的afterPropertiesSet或者自定义的初始化方法)之后被调用。这个时候,bean的属性值已经被填充完毕。返回的bean实例可能是原始bean的一个包装。
二、Bean的生命周期
整个Bean生命周期的调用顺序如图所示:
Bean周期.png
三、实现代码
代码如下:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.core.domain.BaseApprovalEntity;
import org.apache.commons.lang3.ObjectUtils;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class MybatisReflect implements BeanPostProcessor {
private final static Map<String, BaseMapper<?>> MAP_CLASSNAME_TO_MAPPER = new ConcurrentHashMap<>();
private final static Map<String, String> MAP_MAPPER_NAME_TO_CLASS_NAME = new ConcurrentHashMap<>();
public static <T> BaseMapper<T> getMapper(String className) {
return (BaseMapper<T>) MAP_CLASSNAME_TO_MAPPER.get(className);
}
public static <T> BaseMapper<T> getMapper(Class<?> t) {
return (BaseMapper<T>) MAP_CLASSNAME_TO_MAPPER.get(t.getName());
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof MapperFactoryBean) {
Class<?> mapperInterface = ((MapperFactoryBean<?>) bean).getMapperInterface();
Type[] genericInterfaces = mapperInterface.getGenericInterfaces();
if (ObjectUtils.isNotEmpty(genericInterfaces)) {
Type[] actualTypeArguments = ((ParameterizedType) genericInterfaces[0]).getActualTypeArguments();
String typeName = actualTypeArguments[0].getTypeName();
MAP_MAPPER_NAME_TO_CLASS_NAME.put(beanName, typeName);
}
}
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof BaseMapper) {
String className = MAP_MAPPER_NAME_TO_CLASS_NAME.get(beanName);
MAP_CLASSNAME_TO_MAPPER.put(className, (BaseMapper<?>) bean);
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}