Ruoyi implementa el cambio dinámico de fuente de datos desde la base de datos

Uno de los requisitos del proyecto actual es que los datos se pueden consultar dinámicamente, la fuente de datos se puede agregar en la configuración de la página de inicio y luego la fuente de datos se puede vincular al negocio. Al consultar datos, la configuración en el archivo de configuración yml no es fijo.La configuración de la base de datos se basa en la conexión según la fuente de datos almacenada en la tabla de la base de datos vinculada a la empresa.

 Aunque Ruoyi encapsuló el cambio de fuente de datos y especificó la fuente de datos a través de AOP, el método original de Ruoyi solo puede cambiar la fuente de datos existente en el archivo de configuración, lo que significa que si quiero agregar una nueva La fuente de datos debe agregarse a la configuración archivo, y lo mismo ocurre con las modificaciones, lo cual obviamente es muy problemático. No satisface nuestras necesidades.

 

/**
 * 自定义多数据源切换注解
 *
 * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
 *
 * @author ruoyi
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource
{
    /**
     * 切换数据源名称
     */
    public DataSourceType value() default DataSourceType.MASTER;
}

Entonces mi idea es agregar una capa de procesamiento basada en la original de Ruoyi, comentar la notificación circundante escrita originalmente por Ruoyi y usar la notificación previa @Before() para el procesamiento.

 Agregue una nueva enumeración OTHER a la enumeración de la fuente de datos para identificar la fuente de datos de conmutación.

/**
 * 数据源
 * 
 * @author ruoyi
 */
public enum DataSourceType
{
    /**
     * 主库
     */
    MASTER,

    /**
     * 从库
     */
    SLAVE,

    /**
     * 其他
     */
    OTHER
}

 El tipo especificado se juzga en la notificación previa del aspecto. Si es maestro, se usa la fuente de datos predeterminada, el esclavo usa la biblioteca esclava configurada en el archivo de configuración y otros medios usan la fuente de datos existente en la tabla de la base de datos, y luego basado en la solicitud Los parámetros del método obtienen la identificación comercial y luego van a la base de datos para consultar la información de la fuente de datos vinculada a ella, y luego la configuran como la fuente de datos actual. Después de su uso, la fuente de datos se borra a través de la publicación. notificación @Después.

/**
 * 多数据源处理
 * 
 * @author ruoyi
 */
@Log4j2
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{
    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private ISysDataSourceService sysDataSourceService;
    @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
            + "|| @within(com.ruoyi.common.annotation.DataSource)")
    public void dsPointCut()
    {

    }

    @Before("dsPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        logger.info("方法名称: " + method.getName());
        DataSource dataSource = method.getAnnotation(DataSource.class);
        DruidConfig dynamicDataSourceConfig = SpringContextUtils.getBean(DruidConfig.class);
        Map<Object, Object> map = dynamicDataSourceConfig.getTargetDataSources();
        log.info("TargetDataSources==="+map.toString());

        // 通过判断 DataSource 中的值来判断当前方法应用哪个数据源
        String value = String.valueOf(dataSource.value());
        boolean flag;
        String name = "";
        switch (value) {
            case "MASTER":
                flag = true;
                name = DataSourceType.MASTER.name();
                break;
            case "SLAVE":
                flag = true;
                name = DataSourceType.SLAVE.name();
                break;
            case "OTHER":
                flag = true;
               
                name = "OTHER";
                if (map.get(name) != null) {
                    break;
                } else {
                    //获取传入参数
                    Object[] args = joinPoint.getArgs();
                    JSONObject json = (JSONObject) args[0];
                    Long dataSourceId = json.getLong("dataSourceId");
                    log.info("获取的数据源ID=="+dataSourceId);
                    //从传入参数获取业务ID查找数据源信息,设置数据源信息
                    SysDataSource source = sysDataSourceService.getById(dataSourceId);
                    String url = source.getDbUrl();
                    String username = source.getDbUsername();
                    //密码解密
                    String password = SecurityUtil.jiemi(source.getDbPwd());
                    log.info("解密后密码=="+password);
                    log.info("数据源切换:" + url);

                    DruidDataSource s = dynamicDataSourceConfig.createDataSource(name, url, username,
                            password, source.getDbDriver());
                }
                break;
            default:
                flag = false;
                break;
        }

        if (!flag) {
            logger.error("************注意************");
            name = DataSourceType.MASTER.name();
            logger.info("加载到未知数据源,系统自动设置数据源为默认数据源!");
        }
        DynamicDataSource.setDataSource(name);
        //设置成数据源
        DynamicDataSourceContextHolder.setDataSourceType(name);
        logger.info("当前数据源: " + name);
        logger.info("当前数据源: " + ((DruidDataSource) map.get(name)).getUrl());
        logger.info("set datasource is " + name);
    }


    @After("dsPointCut()")
    public void doAfter() {
        logger.info("*********准备清除数据源*********");
        DynamicDataSource.clearDataSource();
        DynamicDataSourceContextHolder.clearDataSourceType();
        logger.info("*********数据源清除成功*********");
    }

Cabe señalar que el tipo de enumeración recién agregado se agrega al archivo de configuración druidConfig.

 Cuando necesite cambiar de fuente de datos, simplemente agregue anotaciones a la clase o método

@DataSource(valor = DataSourceType.OTHER)

Supongo que te gusta

Origin blog.csdn.net/weixin_53160419/article/details/131373123
Recomendado
Clasificación