Spring技巧MybatisPlus

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;
}

说明:

二、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);
    }

}
上一篇 下一篇

猜你喜欢

热点阅读