若依ruoyi框架增加2个以上的数据源配置

本文介绍了如何在SpringBoot项目中配置Druid连接池,实现数据库主库、从库和新添加的聊天数据库(如chatgpt)的多数据源管理,并展示了如何在Mapper接口上使用@DataSource注解动态切换数据源进行查询。
该文章已生成可运行项目,

1.配置application.yml文件

  # 数据库配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://xxx/xxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: xxx
        password: xxx
      # 从库数据源
      slave:
        # 从数据源开关/默认关闭
        enabled: true
        url: jdbc:mysql://xxx/xxx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
        username: xxx
        password: xxx
      # 这里就是新增加的数据源,比如是chatgpt库名
      chatgpt:
        # 从数据源开关/默认关闭
        enabled: true
        url: jdbc:mysql://xxx/chatgpt?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
        username: chatgpt
        password: chatgpt

2.增加枚举DataSourceType

package com.ruoyi.common.enums;

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

    /**
     * 从库
     */
    SLAVE,
    /**新增加的库枚举*/
    CHATGPT
}

3.增加数据源加载DruidConfig

package com.ruoyi.framework.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.config.properties.DruidProperties;
import com.ruoyi.framework.datasource.DynamicDataSource;

/**
 * druid 配置多数据源
 * 
 * @author ruoyi
 */
@Configuration
public class DruidConfig
{
    @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

	//初始化将新的数据源druid对象,上面两个是原来的2个数据源,拷贝改
    @Bean
    @ConfigurationProperties("spring.datasource.druid.chatgpt")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.chatgpt", name = "enabled", havingValue = "true")
    public DataSource chatgptDataSource(DruidProperties druidProperties)
    {
        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }

    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource)
    {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
        //将新的数据源对象加载到DataSource去
        setDataSource(targetDataSources, DataSourceType.CHATGPT.name(), "chatgptDataSource");
        return new DynamicDataSource(masterDataSource, targetDataSources);
    }
    
    //...
}

4.编写测试Mapper

package com.ruoyi.xxx.mapper;

import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public interface TestChatgptMapper {

	//切换数据源就用这个注解,跟框架自带的2个使用方式没有差别
	//假设chatgpt数据库用有个user表可以拿来查询
    @DataSource(value= DataSourceType.CHATGPT)
    @Select("select * from user")
    List<Map> selectAll();

}

5.编写测试类使用

//...
@Autowired
private TestChatgptMapper testChatgptMapper;
@Test
void test7(){
    List<Map> res = testChatgptMapper.selectAll();
    System.out.println(res.toString());
}
//...
本文章已经生成可运行项目
<think>首先,用户的问题是基于之前的引用内容,询问如何在若依(RuoYi框架中集成第三方报表工具来导出所有数据。用户特别提到“导出所有数据”,所以我的回答需要聚焦在数据导出的实现方法上。 从引用中: - 引用[1]介绍了集成JimuReport报表工具,用于生成报表。 - 引用[2]提供了集成JimuReport的具体代码示例,包括添加包扫描和白名单设置。 - 引用[3]讨论了数据报表系统的痛点,如数据分散、报表生成复杂等。 - 引用[4]描述了导出数据的逻辑,如填充数据到单元格。 用户的上一个问题可能是关于若依框架集成报表工具的,但我没有之前的对话记录。系统指令说“参考用户上一次的问题和你的回答”,但这里没有提供之前的对话,所以我只能基于当前引用和问题来回答。 关键点: - 用户想导出所有数据,这可能意味着导出整个数据集到报表。 - JimuReport是一个强大的工具,支持报表设计和导出。 我的回答需要: 1. **结构清晰**:逐步解释实现方法。 2. **真实可靠**:基于引用内容,确保准确性。 3. **使用中文**。 4. **格式要求**:行内数学表达式用$...$,独立公式用$$...$$(但这里可能不需要数学公式)。 5. **生成相关问题**:在末尾添加相关问题。 6. **引用标识**:在引用段落末尾添加[^n]。 步骤: 1. **理解集成方法**: - 从引用[2]:集成JimuReport需要修改SpringBoot配置,添加包扫描和设置白名单。 - 代码示例:`@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages = {"org.jeecg.modules.jmreport", "com.ruoyi"} )` - 设置白名单:在若依的鉴权机制中添加jmreport路径白名单,避免token校验。 2. **导出数据实现**: - 引用[4]描述了导出逻辑:填充数据到sheet,根据数据范围创建行和单元格。 - JimuReport应该有自己的API或方式来定义报表模板和导出数据。 - 要导出所有数据,需要从数据库中查询所有数据,然后填充到报表中。 - 可能涉及:创建报表模板、定义数据源、执行导出。 3. **具体方法**: - **步骤1:集成JimuReport** - 添加依赖:在pom.xml中添加JimuReport的依赖。 - 配置包扫描:如引用[2]所示。 - 设置白名单:在若依的SecurityConfig中,添加JimuReport的URL路径到免认证列表。 - **步骤2:设计报表模板** - 使用JimuReport的设计器创建报表模板,定义字段、格式等。 - 模板应包含所有需要导出的字段。 - **步骤3:实现数据导出** - 在代码中,查询数据库获取所有数据。 - 使用JimuReport的API将数据填充到模板中。 - 导出为Excel或其他格式。 - 参考引用[4]:循环创建行和单元格,填充数据。 4. **确保完整导出**: - 要导出所有数据,确保在查询时没有分页限制。 - 在若依框架中,可能需要修改服务层或控制层代码,添加一个导出所有数据的方法。 5. **代码示例**: - 提供一个简单的代码片段,展示如何调用JimuReport导出数据。 - 例如,在Controller中添加一个导出方法。 回答结构: - 介绍:简要解释集成JimuReport导出数据的方法。 - 详细步骤:分步说明实现过程,包括配置、模板设计、代码实现。 - 注意事项:提到性能考虑(如大数据量导出)。 - 引用:在相关部分添加引用标识。 - 相关问题:在末尾生成相关问题。 生成相关问题: - 基于主题,如优化导出性能、处理大数据量、其他报表工具集成等。 最终回答大纲: 1. 介绍若依框架集成JimuReport导出数据的方法。 2. 步骤: a. 集成JimuReport框架:依赖、配置、白名单。 b. 设计报表模板。 c. 实现数据查询和导出逻辑。 3. 代码示例。 4. 注意事项。 5. 相关问题。 </think> ### 若依框架集成第三方报表工具导出所有数据的实现方法 在若依(RuoYi框架中集成JimuReport等第三方报表工具导出所有数据,需结合框架的安全机制和报表工具的数据处理能力。以下是基于引用内容的逐步实现方法,确保数据完整导出(如导出整个数据库表或查询结果集)。 #### 1. **集成报表工具到若依框架** - **添加依赖与配置扫描包**: 在若依的Spring Boot启动类中,添加JimuReport的包扫描路径,确保报表组件能被框架加载。参考引用[2],修改`RuoYiApplication`类: ```java @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages = {"org.jeecg.modules.jmreport", "com.ruoyi"} ) public class RuoYiApplication { // 主方法保持不变 } ``` 这允许JimuReport与若依共享上下文,避免组件扫描冲突[^2]。 - **设置白名单**: 若依的鉴权机制会对API进行token校验。需在安全配置类(如`SecurityConfig`)中添加JimuReport相关路径白名单,避免导出请求被拦截: ```java @Override protected void configure(HttpSecurity http) throws Exception { http // 其他配置... .authorizeRequests() .antMatchers("/jmreport/**").permitAll() // 添加JimuReport路径白名单 .anyRequest().authenticated(); } ``` 这确保报表导出接口无需登录即可访问(适用于匿名导出场景)。 #### 2. **设计报表模板** - **使用JimuReport设计器**: 通过JimuReport的Web设计器创建报表模板: - 定义数据源:连接若依的数据库(如MySQL)。 - 设计布局:添加表格、图表等元素,映射到数据库字段(如用户表的所有列)。 - 设置导出格式:支持Excel、PDF等,模板中指定“导出所有数据”选项,避免分页限制。 直观的设计界面简化了复杂报表的生成,非技术人员也能操作[^1]。 #### 3. **实现数据导出逻辑** - **查询所有数据**: 在服务层(Service)中,编写查询方法获取全量数据。避免使用若依自带的分页插件,确保返回所有记录: ```java @Service public class DataExportService { @Autowired private UserMapper userMapper; // 假设导出用户表 public List<User> exportAllData() { return userMapper.selectAll(); // 自定义Mapper方法,查询无分页数据 } } ``` - **调用报表API填充数据**: 在控制器(Controller)中,使用JimuReport的API将数据填充到模板并导出。参考引用[4]的填充逻辑: ```java @RestController @RequestMapping("/export") public class ExportController { @Autowired private DataExportService dataExportService; @GetMapping("/all") public void exportAll(HttpServletResponse response) { List<User> dataList = dataExportService.exportAllData(); // 获取所有数据 // 使用JimuReport的引擎填充数据 JmReportUtil.exportExcel( "template.jmx", // 报表模板文件 dataList, // 数据集 "all_data.xlsx", // 导出文件名 response ); } } ``` 关键点: - 数据填充基于循环:遍历数据集合,逐行逐单元格写入(类似引用[4]描述的“遍历List<Object[]>集合”)[^4]。 - 处理策略:通过映射规则(如object[0]为值,object[1]为格式策略)确保数据准确导出。 - 导出性能:大数据量时需优化查询和内存管理(如分批处理)。 #### 4. **注意事项** - **数据一致性**:确保导出前数据已同步,避免脏读。 - **安全风险**:开放白名单路径时,限制IP或添加二次验证,防止未授权访问。 - **性能优化**: - 大数据导出(如百万级)使用异步任务或分片导出,防止内存溢出。 - 引用[3]指出,系统扩展性可通过RuoYi的模块化设计应对,例如添加缓存机制提升实时性[^3]。 - **测试验证**:在若依开发环境中测试导出功能,检查数据完整性和格式正确性。 通过以上步骤,JimuReport与若依框架无缝集成,实现高效、完整的数据导出,解决了传统报表生成的复杂性(如引用[3]所述的数据分散和手动操作问题)[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cgv3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值