Ruoyi implementiert den dynamischen Datenquellenwechsel aus der Datenbank

Eine der Anforderungen des aktuellen Projekts besteht darin, dass die Daten dynamisch abgefragt werden können, die Datenquelle in der Front-End-Seitenkonfiguration hinzugefügt werden kann und dann die Datenquelle an das Unternehmen gebunden werden kann. Beim Abfragen von Daten ist die Konfiguration in Die YML-Konfigurationsdatei ist nicht festgelegt. Die Datenbankkonfiguration basiert auf der Verbindung basierend auf der Datenquelle, die in der an das Unternehmen gebundenen Datenbanktabelle gespeichert ist.

 Obwohl Ruoyi die Datenquellenumschaltung gekapselt und die Datenquelle über AOP angegeben hat, kann die ursprüngliche Methode von Ruoyi nur die vorhandene Datenquelle in der Konfigurationsdatei wechseln, was bedeutet, dass, wenn ich eine neue hinzufügen möchte, die Datenquelle zur Konfiguration hinzugefügt werden muss Datei, und das Gleiche gilt für Änderungen, was natürlich sehr mühsam ist. Entspricht nicht unseren Bedürfnissen.

 

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

Dann besteht meine Idee darin, eine Verarbeitungsebene basierend auf Ruoyis Original hinzuzufügen, die umgebende Benachrichtigung, die ursprünglich von Ruoyi geschrieben wurde, auszukommentieren und die Vorbenachrichtigung @Before() für die Verarbeitung zu verwenden

 Fügen Sie der Datenquellenaufzählung eine neue Enumeration OTHER hinzu, um die wechselnde Datenquelle zu identifizieren.

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

    /**
     * 从库
     */
    SLAVE,

    /**
     * 其他
     */
    OTHER
}

 Der angegebene Typ wird in der Vorabbenachrichtigung des Aspekts beurteilt. Wenn es sich um einen Master handelt, wird die Standarddatenquelle verwendet, während der Slave die in der Konfigurationsdatei konfigurierte Slave-Bibliothek verwendet und auf andere Weise die in der Datenbanktabelle vorhandene Datenquelle verwendet Basierend auf der Anforderung erhalten die Parameter der Methode die Geschäfts-ID und gehen dann zur Datenbank, um die daran gebundenen Datenquelleninformationen abzufragen und sie dann als aktuelle Datenquelle festzulegen. Nach der Verwendung wird die Datenquelle durch den Beitrag gelöscht Benachrichtigung @After.

/**
 * 多数据源处理
 * 
 * @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("*********数据源清除成功*********");
    }

Es ist zu beachten, dass der neu hinzugefügte Aufzählungstyp zur druidConfig-Konfigurationsdatei hinzugefügt wird.

 Wenn Sie die Datenquelle wechseln müssen, fügen Sie einfach Anmerkungen zur Klasse oder Methode hinzu

@DataSource(value = DataSourceType.OTHER)

Ich denke du magst

Origin blog.csdn.net/weixin_53160419/article/details/131373123
Empfohlen
Rangfolge