1.JDBC配置
- pom.xml
<!--引入mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--引入JDBC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
- application.yml
spring:
# 数据源的相关配置都在DataSourceProperties里面;
datasource:
username: root
password: 123456
url: jdbc:mysql://172.16.40.143:3306/jdbc
driver-class-name: com.mysql.jdbc.Driver
#自动运行SQL
schema:
- classpath:sql/department.sql
- classpath:sql/employee.sql
initialization-mode: always
- test
@Autowired
DataSource dataSource;
@Test
public void contextLoads() throws SQLException {
//默认是用 com.zaxxer.hikari.HikariDataSource作为数据源;
System.out.println(dataSource.getClass());
Connection connection = dataSource.getConnection();
//HikariProxyConnection@485237151 wrapping com.mysql.jdbc.JDBC4Connection@692e028d
System.out.println(connection);
connection.close();
}
2.自动配置原理:
- 参考DataSourceConfiguration.Java,根据配置创建数据源,默认使用HikariDataSource连接池;可以使用spring.datasource.type指定自定义的数据源类型;
- SpringBoot默认可以支持org.apache.tomcat.jdbc.pool.DataSource、HikariDataSource、BasicDataSource
- 自定义数据源类型
abstract class DataSourceConfiguration {
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
name = {"spring.datasource.type"}
)
static class Generic {
Generic() {
}
@Bean
public DataSource dataSource(DataSourceProperties properties) {
//使用DataSourceBuilder创建数据源,利用反射创建响应type的数据源,并且绑定相关属性
return properties.initializeDataSourceBuilder().build();
}
}
public DataSourceBuilder<?> initializeDataSourceBuilder() {
return DataSourceBuilder.create(this.getClassLoader()).type(this.getType()).driverClassName(this.determineDriverClassName()).url(this.determineUrl()).username(this.determineUsername()).password(this.determinePassword());
}
public static DataSourceBuilder<?> create(ClassLoader classLoader) {
//使用DataSourceBuilder创建数据源
return new DataSourceBuilder(classLoader);
}
public T build() {
//利用反射创建响应type的数据源
Class<? extends DataSource> type = this.getType();
DataSource result = (DataSource)BeanUtils.instantiateClass(type);
this.maybeGetDriverClassName();
this.bind(result);
return result;
}
- 导入了DataSourceInitializationConfiguration:ApplicationListener(一个监听器);
作用:runScripts();运行建表语句和运行插入数据的sql语句;
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
@Configuration
@Import({DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class})
class DataSourceInitializationConfiguration {
class DataSourceInitializerInvoker implements ApplicationListener<DataSourceSchemaCreatedEvent>, InitializingBean {
private void initialize(DataSourceInitializer initializer) {
try {
this.applicationContext.publishEvent(new DataSourceSchemaCreatedEvent(initializer.getDataSource()));
if (!this.initialized) {
this.dataSourceInitializer.initSchema();
this.initialized = true;
}
} catch (IllegalStateException var3) {
logger.warn("Could not send event to complete DataSource initialization (" + var3.getMessage() + ")");
}
}
public void onApplicationEvent(DataSourceSchemaCreatedEvent event) {
DataSourceInitializer initializer = this.getDataSourceInitializer();
if (!this.initialized && initializer != null) {
initializer.initSchema();
this.initialized = true;
}
}
public void initSchema() {
List<Resource> scripts = this.getScripts("spring.datasource.data", this.properties.getData(), "data");
if (!scripts.isEmpty()) {
if (!this.isEnabled()) {
logger.debug("Initialization disabled (not running data scripts)");
return;
}
String username = this.properties.getDataUsername();
String password = this.properties.getDataPassword();
this.runScripts(scripts, username, password);
}
默认只需要将文件命名为:
schema-*.sql、data-*.sql
默认规则:schema.sql,schema-all.sql;
可以使用
schema:
- classpath:department.sql
指定位置
public boolean createSchema() {
List<Resource> scripts = this.getScripts("spring.datasource.schema", this.properties.getSchema(), "schema");
if (!scripts.isEmpty()) {
if (!this.isEnabled()) {
logger.debug("Initialization disabled (not running DDL scripts)");
return false;
}
String username = this.properties.getSchemaUsername();
String password = this.properties.getSchemaPassword();
this.runScripts(scripts, username, password);
}
return !scripts.isEmpty();
}
public void initSchema() {
List<Resource> scripts = this.getScripts("spring.datasource.data", this.properties.getData(), "data");
if (!scripts.isEmpty()) {
if (!this.isEnabled()) {
logger.debug("Initialization disabled (not running data scripts)");
return;
}
String username = this.properties.getDataUsername();
String password = this.properties.getDataPassword();
this.runScripts(scripts, username, password);
}
}
private List<Resource> getScripts(String propertyName, List<String> resources, String fallback) {
if (resources != null) {
return this.getResources(propertyName, resources, true);
} else {
String platform = this.properties.getPlatform();
List<String> fallbackResources = new ArrayList();
fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");
fallbackResources.add("classpath*:" + fallback + ".sql");
return this.getResources(propertyName, fallbackResources, false);
}
}
- 操作数据库:自动配置了JdbcTemplate操作数据库
@Configuration
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({JdbcProperties.class})
public class JdbcTemplateAutoConfiguration {
@Controller
public class HelloController {
@Autowired
JdbcTemplate jdbcTemplate;
@ResponseBody
@GetMapping("/query")
public Map<String,Object> map (){
List<Map<String,Object>> list = jdbcTemplate.queryForList("select * from department");
return list.get(0);
}
}