`

jboot的动态配置数据源

阅读更多
Jboot通过ShardingJDBC实现分库分表,但是分库分表函数主要是通过字段值进行计算,但如果分库方式与数据无关,并且分库需要在运行时动态新增配置就无法满足要求。
下面是通过改造基本Model类,并动态配置数据源的方法:

1、新增数据源缓存类
   注意,configName要使用线程本地类,JBoot非线程安全。
public class DataConfigName {
    private static DataConfigName me;
    @JSONField(serialize = false)
    transient private ThreadLocal<String> configName = new ThreadLocal<>();

    private DataConfigName(){}

    public static DataConfigName getInstance(){
        if(me == null){
            me = new DataConfigName();
        }
        return me;
    }

    public void setConfigName(String name){
        configName.set(name);
    }

    public String getConfigName(){
        String name = configName.get();
        if(null == name){
            name = DbKit.MAIN_CONFIG_NAME;
        }
        return name;
    }
}


2、修改Model基础类
   JBoot操作数据库主要通过Model来实现,框架提供了基础类JBootModel,需要对这个类进行扩展,覆盖所有方法,如下所示,方法中都增加了use子句,实现数据源的切换,否则会使用默认数据源:
public class GlueModel<M extends GlueModel<M>> extends JbootModel<M> {
    public GlueModel(){};
    ……
    

    public M use(String configName) {
        return super.use(configName);
    }

    M superUse(String configName) {
        return super.use(configName);
    }

    public boolean saveOrUpdate() {
        this.use(DataConfigName.getInstance().getConfigName());
        return super.saveOrUpdate();
    }

    public boolean save() {
        this.use(DataConfigName.getInstance().getConfigName());
        return super.save();
    }
    ……
}


3、替换所有Db类的操作,增加use子句,如:
public class TransactionModel extends GlueModel<TransactionModel> {

    ……

    public static TransactionModel getByTno(String tno){
        ……
        Record record = Db.use(DataConfigName.getInstance().getConfigName()).findFirst(sql);
        ……
    }
    ……
}


4、创建一个数据源动态管理类。
Jboot虽然在2.1.2版本的DataSourceConfigManager类中开放了addConfig方法,但由于Db类是属于JFinal框架的,无法影响到,因此需要调用JFinal的DbKit的addConfig方法完成数据源的新增。
下面的代码只提供了从默认数据库获取数据源配置参数的实现方式,如果需要通过本地配置文件、网络文件等方式,可参考自行添加
public class DynamicDataSourceManager {
    /**
     * 从数据库获取数据源配置参数
     * @param tableName
     * @param corpId
     * @return
     */
    public static Config loadConfigFromDB(String tableName, String corpId){
        Config config = DbKit.getConfig(corpId);
        if(null == config) {
            SqlPara sql = new SqlPara();
            sql.setSql("select * from " + tableName + " where corpid=?").addPara(corpId);
            List<Record> records = Db.find(sql);
            if (null != records && records.size()>0) {
                Record record = records.get(0);
                DataSourceConfig dataSourceConfig = new DataSourceConfig();
                dataSourceConfig.setName(record.getStr("corpid"));
                dataSourceConfig.setType(DataSourceConfig.TYPE_MYSQL);
                dataSourceConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
                dataSourceConfig.setUrl("jdbc:mysql://"
                        + record.getStr("write_host")
                        + ":" + record.getStr("write_port")
                        + "/"
                        + record.getStr("write_database")
                        + "?useUnicode=true&characterEncoding="
                        + record.getStr("charset")
                        + "&useSSL=false");
                dataSourceConfig.setUser(record.getStr("write_username"));
                dataSourceConfig.setPassword(record.getStr("write_password"));
                dataSourceConfig.setPoolName(record.getStr("write_database"));

                DataSource dataSource = new DataSourceBuilder(dataSourceConfig).build();

                config = new Config(
                        record.getStr("corpid"),
                        dataSource,
                        new MysqlDialect(),
                        false,
                        false,
                        DbKit.DEFAULT_TRANSACTION_LEVEL,
                        IContainerFactory.defaultContainerFactory,
                        new EhCache()
                );
                DbKit.addConfig(config);
            }
        }
        return config;
    }
}


5、在切片方法或入口方法中实现数据源的配置
    ……
    if(null != corpId){
        Config config = DynamicDataSourceManager.loadConfigFromDB("corp_database", corpId);
        if(null != config) {
            DataConfigName.getInstance().setConfigName(corpId);
        }
     }
    ……


通过上述修改即可完成动态分库处理,实际的Model中无需再做任何特殊处理。
分享到:
评论

相关推荐

    jboot WebSocketTest

    首先,我们需要在Jboot的配置文件中开启WebSocket支持,这通常在`jboot.properties`中完成,通过设置`jboot.web.websocket.enable=true`来启用WebSocket服务。 接着,创建WebSocket处理器类,这是WebSocket的核心...

    jboot+dubbo+nacos例子.zip

    在实际项目中,开发者需要配置JBoot的启动类,使其实例化Dubbo服务提供者或消费者,并集成Nacos的相关配置,以完成服务的注册、发现和调用。此外,还需要编写业务逻辑代码,定义服务接口和实现,以及服务的调用逻辑...

    jboot多模块打包例子.zip

    它支持热部署、AOP切面编程、动态数据源、分布式事务管理等特性,并且对微服务架构有很好的支持。JBoot特别适合于构建高并发、高性能的企业级应用。 二、Maven多模块项目 Maven是Java项目管理工具,其多模块项目...

    jboot开发资源

    - **数据库支持**:集成MyBatis Plus,简化数据库操作,同时支持多数据源配置。 - **缓存机制**:内置Redis、Memcached等缓存支持,提高数据读取速度。 - **安全防护**:提供统一的权限控制、CSRF防护、SQL注入...

    jboot远程调用笔记和demo,能用!

    2. 配置服务提供者:在JBoot的配置文件中,设置Motan的基本参数,如服务端口、服务版本、超时时间等。同时,你需要指定服务的接口和实现类。 3. 注解服务接口:在服务接口类上使用`@RpcService`注解,指定接口名和...

    基于VueiView开发的jboot前台

    【标题】"基于Vue iView开发的jboot前台"是一个使用Vue.js框架和iView UI库构建的前端项目,主要用于实现动态路由权限控制、多语言支持以及提供简洁美观的用户界面。这个项目与后端框架jboot紧密结合,实现了前端与...

    Jboot微服务框架 v4.1.5.zip

    4. **分布式缓存**:Jboot内置了对Redis的支持,可以轻松实现数据缓存,提高系统性能。 5. **配置管理**:Jboot的配置文件支持YAML格式,且支持配置热更新,无需重启服务即可生效。 6. **AOP支持**:Jboot集成...

    jboot-master.zip

    对于初学者,可以从官方文档开始,了解Jboot的基本概念和配置。通过实际创建一个简单的项目,如搭建一个RESTful API服务器,熟悉其路由、数据库操作和AOP等特性。此外,参与社区讨论,参考已有的开源项目,可以加速...

    基于JBoot的简单Admin.zip

    基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于JBoot的简单Admin.zip基于...

    Jboot微服务框架 v3.17.1.zip

    而"jboot-v3.17.1"文件夹可能包含了框架的所有源代码和必要的配置文件,开发者可以通过解压和导入到IDE中,直接开始他们的开发工作。 总的来说,Jboot v3.17.1版本提供了一套完整的微服务解决方案,无论是对于初学...

    jboot-admin是基于jboot全家桶构建的微服务实战项目,以微服务快速迭代开发为架构思想,-jboot.zip

    jboot-admin是一个采用jboot框架为核心的微服务实战项目,旨在利用jboot的全栈能力,实现高效、快速的微服务迭代开发。jboot是一个轻量级、高性能的Java开发框架,它在传统的Java EE基础上进行了优化,提供了更简洁...

    jboot 入门案例

    Jboot是一个基于JFinal 和 Undertow...提供了AOP、RPC、分布式缓存、限流、降级、熔断、统一配置中心、swagger api自动生成、Opentracing数据追踪、metric数据监控、分布式session、代码生成器、shiro安全控制等功能。

    jboot是一个基于jfinalundertow开发的一个类似springboot的开源框架

    jboot是一个基于jfinal、undertow开发的一个类似springboot的开源框架, 我们已经在正式的商业上线项目中使用。她集成了代码生成,微服务,MQ,RPC,监控等功能, 开发者使用及其简单。

    jboot-admin是基于jboot全家桶构建的微服务实战项目.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的)。另外,您不会使用资源的话(这种情况不支持退款),也可以找我们帮助(需要...

    基于 JFinal 的国产微服务框架,SpringCloud 之外的另一个选择

    4. **数据库支持**:Jboot 支持多数据源,包括 MySQL、Oracle、SQLServer 等,还提供了 ORM 插件,简化数据库操作。同时,它内置了对 Redis、MongoDB 等 NoSQL 数据库的支持。 5. **AOP 支持**:Jboot 基于 JFinal ...

    Jboot微服务框架-其他

    提供了AOP、RPC、分布式缓存、限流、降级、熔断、统一配置中心、swagger api自动生成、Opentracing数据追踪、metrics数据监控、分布式session、代码生成器、shiro安全控制等功能。 Jboot 的核心组件 1、MVC (基于...

    SSH configuration

    3. 添加Hibernate框架:导入Hibernate的库,创建hibernate.cfg.xml配置文件,配置数据源、实体类和映射文件。 4. 添加Spring框架:引入Spring的核心库,创建applicationContext.xml配置文件,配置bean,实现依赖注入...

    Jboot是专为大型分布式项目和微服务而生.rar

    Jboot 是一个基于 JFinal、JFinal-Undertow、Dubbo、Seata、Sentinel、ShardingSphere、Nacos 等开发的微服务框架, 帮助...5、基于 Apollo 和 Nacos 的分布式配置中心 6、基于 EhCache 和 Redis 的分布式二级缓存

Global site tag (gtag.js) - Google Analytics