小弟最近需要使用Spring Boot连接两个数据库,于是就开始折腾了。如果想要配置两个数据源,我们需要先学会如何自定义一个数据源,所以这篇博客主要是讲如何自定义一个数据源,需要自定义两个或多个的朋友请戳:
通常来说,我们在配置数据源的时候,会选择使用Spring Boot为我们提供的配置项,如下所示:
spring:
#MySQL数据库相关配置
datasource:
#JDBC链接地址
url: jdbc:mysql://localhost:3306/DATABASENAME?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&&serverTimezone=UTC
#用户名
username: USERNAME
#用户名对应的密码
password: PASSWORD
#数据库连接池类型
type: com.alibaba.druid.pool.DruidDataSource
#数据库驱动
driver-class-name: com.mysql.cj.jdbc.Driver
我们可以通过Spring Boot的默认配置项很快的就完成一个数据库的相关配置,尤其是当你在使用IDEA的时候。
那现在的需求是要自定义一个数据源,也就是说放弃Spring Boot给我们提供的默认配置。
在自定义配置之前,我们需要简单了解一下Spring Boot加载配置的原理,实际上就是将你的application.properties或者是application.yml转成一个java对象,然后放到Spring的容器中,然后可以让对应需要这些参数的对象读取到,所以我们最后只是想要放一个带有参数的对象到Spring的容器中。
这种方案非常简单,不容易出错,但是如果后面想修改数据库的配置就需要重新编译比较麻烦。
主要是我们平时用的jdbc的一些参数,比如url,username,password,driver等等,然后要记得使用@Configuration
注解。
package com.baofeidyz.wxapp.config;
//我这里直接把包全部贴出来,如果你发现你的代码没有问题,但是一直报错的朋友,可以检查一下是否引入了正确的包
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
//类名可以随机,但是一定要加上@Configuration注解
@Configuration
public class MyConfig {
//这个public方法将帮助我们生成一个Datasource对象,我们使用@Bean(value="")的方式为这个对象进行标记,后面我们可以通过这个appData找到这个对象并放到Mybatis的相关配置中
@Bean(value = "appData")
//Spring Boot要求至少要有一个@Primary的数据库源
@Primary
public HikariDataSource dataSource() {
HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class).build();
dataSource.setUsername("USERNAME");
dataSource.setPassword("PASSWORD");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/DATABASENAME?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&&serverTimezone=UTC");
System.out.println("============================");
System.out.println(dataSource.toString());
System.out.println(dataSource.isRunning());
System.out.println(dataSource.getCatalog());
System.out.println(dataSource.getUsername());
System.out.println(dataSource.getPassword());
System.out.println(dataSource.getJdbcUrl());
System.out.println("============================");
return dataSource;
}
}
这样子我们就使用自定义配置好了一个数据库源,所以在application.properties 或 是application.yml文件中就无需配置datasource了。
关于这里方法的返回类型是HikariDataSource,而不是DataSource的问题,其实我也不清楚,我有尝试过将返回类型设置为DataSource, 但是最后
System.out.println(dataSource.toString());
打印出来的语句是
HikariDataSource (null)
所以我就直接使用了HikariDataSource
作为返回值,如果有知道这个原因的朋友,麻烦留言告知一下,感谢。
代码如下:
package com.baofeidyz.wxapp.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
//和MyConfig 类一样,这个类名是可以修改的
@Configuration
//basePackages对应的是你的DAO层接口类的包路径
@MapperScan(basePackages = {"com.baofeidyz.wxapp.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory1")
public class MyBatisConfig {
@Autowired
@Qualifier("appData")
private DataSource ds1;
@Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds1); // 使用titan数据源, 连接titan库
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1()); // 使用上面配置的Factory
return template;
}
}
然后大家弄一个junit测试一下就好了。
application.properties
app.datasource.jdbc-url=jdbc:mysql://localhost:3306/DATABASENAME?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&&serverTimezone=UTC
app.datasource.username=DATABASEUSERNAME
app.datasource.password=DATABASEPASSWORD
app.datasource.maximum-pool-size=30
application.yml
app:
datasoure:
jdbc-url: jdbc:mysql://localhost:3306/DATABASENAME?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&&serverTimezone=UTC
username: DATABASEUSERNAME
password: DATABASEPASSWORD
maximum-pool-size: 30
简单解释一下,这个app.datasource其实是可以自定义的,在这里我是按照Spring Boot的官方文档配置的,所以我就使用了他默认的app.datasource。
还有一点,就是在使用application.yml这种格式的时候,一定要注意冒号后面有一个空格。如果你使用的是IDEA,那么格式正确的情况下,会有高亮提示。
Spring Boot 官网对应:https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#howto-configure-a-datasource
仍然是新建一个java类
package com.baofeidyz.wxapp.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class MyConfig {
@Bean(value = "appData")
@Primary
//通过这个注解去读取我们在application.properties或application.yml文件中的参数配置
@ConfigurationProperties(prefix = "app.datasoure")
public HikariDataSource dataSource() {
HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class).build();
return dataSource;
}
}
这样子我们就组装好了一个带有参数的对象,并已经通过@bean
注入到了Spring的容器中,接下来,我们需要配置Mybatis,实际上与方案一中的一模一样。
package com.baofeidyz.wxapp.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
//basePackages对应的是你的DAO层接口类的包路径
@MapperScan(basePackages = {"com.baofeidyz.wxapp.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory1")
public class MyBatisConfig {
@Autowired
@Qualifier("appData")
private DataSource ds1;
@Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(ds1);
return factoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate1() throws Exception {
SqlSessionTemplate template = new SqlSessionTemplate(sqlSessionFactory1());
return template;
}
}
其实这篇文章真的非常的基础,因为很多东西我也不是很明白,还需要继续学习,继续研读。如果您有建议或者您对此的理解,欢迎留言,互相提高,谢谢。