1 環境
plugins {
id 'org.springframework.boot' version '2.3.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'
runtimeOnly 'mysql:mysql-connector-java'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
// https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter
compile group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.2.3'
}
test {
useJUnitPlatform()
}
2 Spring Boot 讀取 yml
2.1 yml 文件注意事項
- 可在小寫字母前增加
-
或_
表示其大寫形式,如userName
與user-name
,user_name
含義是一樣的 - 字符串默認不用加上單引號或者雙引號
- 值使用雙引號不會轉義字符串裏面的特殊字符,例如
name: "zhangsan \n lisi"
,對應的結果會換行 - 值使用單引號會轉義特殊字符,特殊字符最終只是一個普通的字符串,例如
name: ‘zhangsan \n lisi’
對應的結果爲zhangsan \n lisi
2.2 @Value
註解
讀取第一個數據源的 url
@Value("${spring.datasource.first.url}")
private String url;
如果是靜態變量,無法使用上述方式注入,需要:
- 所在類添加
@Component
註解 - 定義一個任意名稱和任意參數名的方法,如下
private static String url;
@Value("${spring.datasource.first.url}")
public void setUrl(String param){
url=param;
}
2.3 @ConfigurationProperties
註解
需要一個 JavaBean 來專門映射配置,精簡案例如下,以此類推:
@Component
@ConfigurationProperties(prefix = "spring.datasource.first")
public class Student {
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
注:prefix 僅描述到配置參數的上一級
2.4 @Environment
註解
@Autowired
private Environment env
public String test() {
System.out.println(env.getProperty("spring.datasource.first.url"));
}
3 案例項目
3.1 主要項目結構
├── src/
│ └── main/
│ ├── java/
│ │ ├── config/
│ │ │ ├── FirstDataSourceConfig.java # 第一個數據源配置
│ │ │ └── SecondDataSourceConfig.java # 第二個數據源配置
│ │ ├── action/
│ │ │ └── Controller.java # 請求處理
│ │ ├── dao/
│ │ │ ├── first/
│ │ │ │ └── FirstDataSourceMapping.java
│ │ │ └── second/
│ │ │ └── SecondDataSourceConfig.java
│ │ ├── service/
│ │ │ └── DataService.java
│ │ └── Application.java # 應用入口
│ └── resources/
│ ├── mapper/
│ │ ├── FirstDataSourceMapping.xml
│ │ └── SecondDataSourceMapping.xml
│ └── application.yml
└── (其他)
application.yml
spring:
profiles:
active: product
datasource:
first:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/onlytest
username: root
password: 123456
second:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/onlytest
username: temp
password: temp
server:
port: 3005
mybatis:
configuration:
call-setters-on-nulls: true
Application.java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
config/FirstDataSourceConfig.java
@Configuration
@MapperScan(basePackages = {"com.dao.first"}, sqlSessionFactoryRef = "firstSqlSessionFactory")
public class FirstDataSourceConfig {
@Value("${spring.datasource.first.url}")
private String url;
@Value("${spring.datasource.first.username}")
private String user;
@Value("${spring.datasource.first.password}")
private String password;
@Value("${spring.datasource.first.driverClassName}")
private String driverClassName;
@Bean(name = "firstDataSource")
@Primary
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder=DataSourceBuilder.create();
dataSourceBuilder.driverClassName(driverClassName);
dataSourceBuilder.url(url);
dataSourceBuilder.password(password);
dataSourceBuilder.username(user);
return dataSourceBuilder.build();
}
@Bean(name = "firstTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean(name = "firstSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("firstDataSource") DataSource masterDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(masterDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/FirstDataSourceMapping.xml"));
return sessionFactory.getObject();
}
}
config/SecondDataSourceConfig.java
@Configuration
@MapperScan(basePackages = {"com.dao.second"}, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {
@Value("${spring.datasource.second.url}")
private String url;
@Value("${spring.datasource.second.username}")
private String user;
@Value("${spring.datasource.second.password}")
private String password;
@Value("${spring.datasource.second.driverClassName}")
private String driverClassName;
@Bean(name = "secondDataSource")
public DataSource dataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(user);
druidDataSource.setPassword(password);
return druidDataSource;
}
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/SecondDataSourceMapping.xml"));
return sessionFactory.getObject();
}
}
dao/first/FirstDataSourceMapping.java
@Repository
public interface FirstDataSourceMapping {
List<LinkedHashMap<String, Object>> GetAllRoot();
}
dao/second/SecondDataSourceMapping.java
@Repository
public interface SecondDataSourceMapping {
List<LinkedHashMap<String, Object>> GetAllTemp();
}
service/DataService.java
@Service
public class DataService {
@Autowired
private FirstDataSourceMapping firstDataSourceMapping;
@Autowired
private SecondDataSourceMapping secondDataSourceMapping;
public List<LinkedHashMap<String, Object>> GetAllRoot() {
return firstDataSourceMapping.GetAllRoot();
}
public List<LinkedHashMap<String, Object>> GetAllTemp() {
return secondDataSourceMapping.GetAllTemp();
}
}
resources/mapper/FirstDataSourceMapping.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="com.dao.first.FirstDataSourceMapping">
<select id="GetAllRoot" resultType="java.util.LinkedHashMap">
<![CDATA[
select * from tableroot
]]>
</select>
</mapper>
resources/mapper/SecondDataSourceMapping.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="com.dao.second.SecondDataSourceMapping">
<select id="GetAllTemp" resultType="java.util.LinkedHashMap">
<![CDATA[
select * from tabletemp
]]>
</select>
</mapper>
action/Controller.java
@RestController
public class Controller {
@Autowired
private DataService dataService;
@RequestMapping(value = "/searchroot", method = RequestMethod.GET)
public void searchRequstHandler1(HttpServletRequest request, HttpServletResponse response) throws Exception {
List<LinkedHashMap<String, Object>> result;
result = dataService.GetAllRoot();
System.out.println(result);
}
@RequestMapping(value = "/searchtemp", method = RequestMethod.GET)
public void searchRequstHandler2(HttpServletRequest request, HttpServletResponse response) throws Exception {
List<LinkedHashMap<String, Object>> result;
result = dataService.GetAllTemp();
System.out.println(result);
}
}