记录一下使用若依框架配置多数据库时踩到的坑,主数据库是mysql,从数据库是oracle
1,修改yml文件,将单一数据源配置修改成多数据源配置
# 数据源配置
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource # 多数据源需要注释下一行配置 下一行配置表示指定mysql的驱动 # driverClassName: com.mysql.cj.jdbc.Driver druid: # 主库数据源 master: url: jdbc:mysql://192.168.1.208:3306/test_online?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true username: root password: rootpwd # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 从库数据源 dzzz: # 从数据源开关/默认关闭 enabled: true # 格式jdbc:oracle:thin:@xxx.xxx.xx.xx:端口号/ServerName ServerName可以自己去数据库查看链接属性了解 也有其他的2种格式可以自行百度了解 url: jdbc:oracle:thin:@192.168.1.18:1521/ORCL username: root password: rootpwd # 初始连接数 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/* # 控制台管理用户名和密码 login-username: login-password: filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true
2,修改pom文件,引入依赖
<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.1.0</version> <scope>system</scope> <systemPath>${pom.basedir}/src/main/resources/lib/ojdbc8.jar</systemPath> </dependency> <!-- https://mvnrepository.com/artifact/cn.easyproject/orai18n --> <dependency> <groupId>cn.easyproject</groupId> <artifactId>orai18n</artifactId> <version>12.1.0.2.0</version> <scope>provided</scope> </dependency>
第一个依赖是从jar包引入依赖,需要自己百度去下载一个
第二个依赖是从maven仓库引入的依赖,引用后更新即可
3,修改多数据源配置类,新增从数据库配置
3.1,修改 多数据源枚举
/** * 数据源 * * @author ruoyi */ public enum DataSourceType { /** * 主库 */ MASTER, /** * 从库 */ SLAVE, /** * 电子证照库 */ DZZZ }
3.2,修改 多数据源配置类
/** * 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); } @Bean @ConfigurationProperties("spring.datasource.druid.dzzz") @ConditionalOnProperty(prefix = "spring.datasource.druid.dzzz", name = "enabled", havingValue = "true") public DataSource dzzzDataSource(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"); setDataSource(targetDataSources, DataSourceType.DZZZ.name(), "dzzzDataSource"); return new DynamicDataSource(masterDataSource, targetDataSources); } /** * 设置数据源 * * @param targetDataSources 备选数据源集合 * @param sourceName 数据源名称 * @param beanName bean名称 */ public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName) { try { DataSource dataSource = SpringUtils.getBean(beanName); targetDataSources.put(sourceName, dataSource); } catch (Exception e) { } } }
3.3,需要使用从库的mapper类标记注解
/** * DzzzMapper 电子证照mapper * @author wqw * @date 20220803 */ public interface DzzzMapper { @DataSource(DataSourceType.DZZZ) void selectByUUID(String uuid); @DataSource(DataSourceType.DZZZ) List<WhLicenseSync16> listAGDZZZInfo(WhLicenseSync16 params); @DataSource(DataSourceType.DZZZ) List<WhLicenseSync16> listTZDZZZInfo(WhLicenseSync16 params); }
4,遇到的一些问题
oracle数据库中有2种字段类型 BLOB 和 NCLOB(具体的解释请自行百度),在创建对象时,BLOB类型的字段对应的是java中的byte[],NCLOB类型的字段对应的是java中的String,而且在配置XML文件时,需要在对应的字段标注jdbcType和typeHandler
4.1,数据库对象
/** * 证书信息 * @author wqw * @date 20220803 */ @Data public class WhLicenseSync16 { /** 主键 */ private String dataUpUuid; /** 证照文件编号 */ private String licenseFileNumber; /** 证照扩展数据 */ private String newAddMetaData; /** 证照版式文件 */ private byte[] licenseFile; /** 证照版式文件格式 */ private Integer fileType; }
4.2,XML配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="***.***.***.***.mapper.DzzzMapper"> <resultMap type="TestModule" id="TestModuleResult"> <result property="dataUpUuid" column="data_up_uuid"/> <result property="licenseFileNumber" column="license_file_number"/> <result property="newAddMetaData" column="new_add_meta_data" jdbcType="NCLOB" typeHandler="org.apache.ibatis.type.NClobTypeHandler"/> <result property="licenseFile" column="license_file" jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler"/> <result property="fileType" column="file_type"/> </resultMap> <sql id="DzzzAGInfoVO"> SELECT DATA_UP_UUID AS "data_up_uuid", LICENSE_FILE_NUMBER AS "license_file_number", NEW_ADD_METADATA AS "new_add_meta_data", LICENSE_FILE AS "license_file", FILE_TYPE AS "file_type", FROM BIZ_TEST_MODULE </sql> <sql id="DzzzQueryParamsCondition"> <where> <if test="dataUpUuid !=null and dataUpUuid !=''"> and DATA_UP_UUID = #{dataUpUuid}</if> and ROWNUM < 10 </where> </sql> <select id="listAGDZZZInfo" parameterType="BizTestModule" resultMap="TestModuleResult"> <include refid="DzzzAGInfoVO"></include> <include refid="DzzzQueryParamsCondition"></include> </select> </mapper>