栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot项目通过数据库配置方式实现动态数据源

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot项目通过数据库配置方式实现动态数据源

废话不多说,直接上代码

一、多数据源实现
  • 配置文件
# 数据源配置
spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        druid:
            # 主库数据源(配置库)
            master:
                url: jdbc:mysql://localhost:3306/config?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                username: root
                password: pwd123456
            # 从库数据源
            slave:
                # 从数据源开关/默认关闭
                enabled: false
                username:
                password:
            # 初始连接数
            initialSize: 5
            # 最小连接池数量
            minIdle: 10
            # 最大连接池数量
            maxActive: 20
            # 配置获取连接等待超时的时间
            maxWait: 60000
            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # 配置一个连接在池中最小生存的时间,单位是毫秒
            minEvictableIdleTimeMillis: 300000
            # 配置一个连接在池中最大生存的时间,单位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # 配置检测连接是否有效
            validationQuery: SELECt 1 FROM DUAL
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            webStatFilter: 
                enabled: true
            statViewServlet:
                enabled: true
                # 设置白名单,不填则允许所有访问
                allow:
                url-pattern: /druid
    public String value() default "MASTER";
}
  • 切面
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{
    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataSource)"
            + "|| @within(com.ruoyi.framework.aspectj.lang.annotation.DataSource)")
    public void dsPointCut()
    {

    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable
    {
        DataSource dataSource = getDataSource(point);

        if (StringUtils.isNotNull(dataSource))
        {
            String dsType = DataSourceType.MASTER.name();
            Object obj = AnnotationResolver.newInstance().resolver(point, dataSource.value());
            if(StringUtils.isNotNull(obj)) {
                dsType = obj.toString();
            }
            DynamicDataSourceContextHolder.setDataSourceType(dsType);
        }

        try
        {
            return point.proceed();
        }
        finally
        {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    
    public DataSource getDataSource(ProceedingJoinPoint point)
    {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource))
        {
            return dataSource;
        }

        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}
  • 注解解析器
public class AnnotationResolver {

    private static AnnotationResolver resolver ;


    public static AnnotationResolver newInstance(){

        if (resolver == null) {
            return resolver = new AnnotationResolver();
        }else{
            return resolver;
        }

    }


    
    public Object resolver(JoinPoint joinPoint, String str) {

        if (str == null) return null ;

        Object value = null;
        if (str.matches("#\{\D*\}")) {// 如果name匹配上了#{},则把内容当作变量
            String newStr = str.replaceAll("#\{", "").replaceAll("\}", "");
            if (newStr.contains(".")) { // 复杂类型
                try {
                    value = complexResolver(joinPoint, newStr);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                value = simpleResolver(joinPoint, newStr);
            }
        } else { //非变量
            value = str;
        }
        return value;
    }


    private Object complexResolver(JoinPoint joinPoint, String str) throws Exception {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        String[] names = signature.getParameterNames();
        Object[] args = joinPoint.getArgs();
        String[] strs = str.split("\.");

        for (int i = 0; i < names.length; i++) {
            if (strs[0].equals(names[i])) {
                Class clazz = args[i].getClass().getSuperclass();
                Method method = clazz.getDeclaredMethod(getMethodName(strs[1]), null);
                Object value = method.invoke(args[i]);
                return getValue(value, 1, strs);
            }
        }

        return null;

    }

    private Object getValue(Object obj, int index, String[] strs) {

        try {
            if (obj != null && index < strs.length - 1) {
                Method method = obj.getClass().getDeclaredMethod(getMethodName(strs[index + 1]), null);
                obj = method.invoke(obj);
                getValue(obj, index + 1, strs);
            }

            return obj;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private String getMethodName(String name) {
        return "get" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
    }


    private Object simpleResolver(JoinPoint joinPoint, String str) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] names = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        for (int i = 0; i < names.length; i++) {
            if (str.equals(names[i])) {
                return args[i];
            }
        }
        return null;
    }

}
  • 注解切换数据源
    @DataSource(value = "#{dsname}")
    @Override
    public TvContext selectTvContextByContextId(Long contextId, String dsname)
    {
        String dsType = DynamicDataSourceContextHolder.getDataSourceType();
        TvContext tvContext = tvContextMapper.selectTvContextByContextId(contextId);
        tvContext.setDsname(dsType);
        return tvContext;
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/975482.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号