在实际开发中,经常可能遇到在一个应用中可能需要访问多个数据库的情况,在需要切换数据源Service或Mapper方法上添加@DataSource注解@DataSource(value = DataSourceType.MASTER),其中value用来表示数据源名称
1.官网配置
1.在DataSourceType类添加数据源枚举
/**
* 从库
*/
SLAVE
2.在DruidConfig配置读取数据源
@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);
}
3.在DruidConfig类dataSource方法添加数据源
setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
数据库配置
我这里使用的是sqlserver2008
master:
url: jdbc:mysql://localhost:3306/xxx?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowMultiQueries=true
username: xxx
password: xxx
driverClassName: com.mysql.cj.jdbc.Driver
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: true
url: jdbc:sqlserver://localhost:1433;DatabaseName=xxx
username: xxx
password: xxx
driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
2.其他配置修改
1.validationQuery 修改
validationQuery 改成 SELECT 1
# 配置检测连接是否有效
validationQuery: SELECT 1
或者直接注释掉
# 配置检测连接是否有效
#validationQuery: SELECT 1
直接注释掉还要注释掉 DruidProperties文中的
//@Value("${spring.datasource.druid.validationQuery}")
//private String validationQuery;
/**
* 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
*/
// datasource.setValidationQuery(validationQuery);
ps:当时改成select * 一直报 “必须指定要从中选择的表。”,一直以为是sql 写错了。validationQuery改成什么可到两个数据库直接查,不报错才可行
2.merge-sql 改为false
3.依赖
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
</dependency>
4.JDBC直连测试
public class TestRy {
public static void main(String[] args) {
// TODO Auto-generated method stub
String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
String dbURL="jdbc:sqlserver://localhost:1433;DatabaseName=xxx";
String userName="xxx";
String userPwd="xxx";
try {
// 加载SQLSERVER JDBC驱动程序
Class.forName(driverName);
//建立数据库连接
Connection connect = DriverManager.getConnection(dbURL, userName,userPwd);
Statement stmt = connect.createStatement();
ResultSet rs = stmt.executeQuery("select * from post;");
while (rs.next()) {
System.out.println(rs.getString("post_id"));
}
} catch (ClassNotFoundException e) {
System.out.print("Error loading SQLServer Driver!");
e.printStackTrace();
} catch (Exception e) {
System.out.print("get data error!");
e.printStackTrace();
}
}
}
3.代码中使用
/**
* service 把sqlserver中的数据同步到mysql
* @return
*/
@Override
public List<SysPost> getSqlServerData() {
// 取sqlserver中的数据
List<SysPost> list = postMapper.selectSqlServerData();
// 处理后 保存到mysql中
return null;
}
/**
* mapper 取sqlserver中的数据
* @return
*/
@DataSource(value = DataSourceType.SLAVE)
List<SysPost> selectSqlServerData();
<select id="selectSqlServerData" resultMap="SysPostResult">
SELECT * FROM post
</select>
ps:两个数据库相应的表字段一样,所以共用对象,不同需要处理