當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
SpringBoot_数据访问-JDBC自动配置原理
生活随笔
收集整理的這篇文章主要介紹了
SpringBoot_数据访问-JDBC自动配置原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
整合最基本的JDBC和數據源,第一個MYSQL,導入mysql驅動的,第二個我們使用原生的JDBC,后面使用Mybatis和JPA再選相應的內容就行了,為了演示方便我也把WEB模塊選中,我們在pom文件里引入的是什么呢,引入是starter-jdbc<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <dependency><!-- 引入web模塊 --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>我們使用最基本的JDBC的時候呢,引入這兩個模塊,一個是JDBC,一個是MYSQL驅動,我們讓他自動導入,接下來我們要看如何配置,才能跟數據庫交互呢,我們連上虛擬機的數據庫,我已經在這啟動起來了,啟動起來以后我們用客戶端連上,我們把mysql啟動起來,我們數據庫啟動起來了,我們要怎么連上數據庫呢,有了Springboot我們只需要寫相應的配置就行了,那我們來到src/main/resources下,就在這寫配置,寫什么配置呢,spring.datasource數據源,datasource里面有一些屬性,比如我們寫數據庫要用的username,spring.datasource.username=rootspring.datasource.password=123456比如我們要連的url地址,我們專門來創建一個測試庫,day20,我們就連上他來操作,配置URL,spring.datasource.url=jdbc:mysql://localhost:3306/day20我們驅動的類名spring.datasource.driver-class-name=com.mysq.jdbc.Driver這樣一配就算是好了我們可以來測試一下,我們來到test類里面
#debug=true
#server.port=8081#server.context-path=/boot02spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=truelogging.level.com.learn=trace
#logging.file=D:/springboot.log
logging.file=springboot.log
#logging.path=/spring/log
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd} ==== [%thread] %-5level ==== %logger{50} ==== %msg%n
#spring.resources.static-locations=classpath:/hello,classpath:/learnspring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/day20
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
DataSource我們讓他自動注入,從容器中拿到的數據源是什么,再從數據源里拿一條鏈接,看能不能拿到這個鏈接,看到數據源用的是這種,class org.apache.tomcat.jdbc.pool.DataSource,他用的是tomcat數據源,連接ProxyConnection[PooledConnection[com.mysql.jdbc.JDBC4Connection@60b34931]],這種配置的默認規則就是這樣,我們想要訪問數據庫,只需要做一個簡單的配置,就是這一塊配置,配置的效果,默認的是tomcat.jdbc數據源,他作為數據源
package com.learn.springboot;import java.sql.Connection;
import java.sql.SQLException;import javax.sql.DataSource;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;/*** SpringBoot單元測試*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDataJDBCApplicationTests {@AutowiredDataSource dataSource;@Testpublic void contextLoads() throws SQLException {// org.apache.tomcat.jdbc.pool.DataSourceSystem.out.println(dataSource.getClass());Connection connection = dataSource.getConnection();System.out.println(connection);connection.close();}
}
包括我們這一塊的配置,它是Spring.jdbc,我們點進來,其實跟我們這個類有關的,數據源所有的配置都在DataSourceProperties里面,為什么是這樣的效果,包括我們可以自動裝配到數據源,而且springboot使用tomcat.jdbc的連接池作為數據源的,我們可以看一下數據源自動配置原理,這個原理我們可以打開自動配置包org.springframework.boot.autoconfigure.jdbc這里都是和數據源配置的,配置原理就是在這個包下,我來抓住幾個比較重要的來給大家看一下,第一個這里有一個DataSourceAutoConfiguration,這里是數據源的自動配置,DataSourceConfiguration,這里叫數據源的配置,這里的@Bean來給容器中添加組件,都是加DataSource,這個類就是來數據源的,但是加哪些數據源,根據各種判斷,如果你導入了tomcat.jdbc連接池,并且你配的spring.datasource.type是jdbc,如果你沒配他也會認為你是配了的/*** Tomcat Pool DataSource configuration.*/
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type",
havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)
static class Tomcat extends DataSourceConfiguration {這個時候就導入tomcat.jdbc的數據源,否則如果是其他情況,/*** Hikari DataSource configuration.*/
@ConditionalOnClass(HikariDataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type",
havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
static class Hikari extends DataSourceConfiguration {如果是Hikari,而且你在type里面指定了HikariDataSource,那么他也能創建這種數據源,參考DataSourceConfiguration,根據配置創建數據源,默認使用tomcat連接池的,那他作為數據源的,我們可以使用什么指定呢,可以使用spring.datasource.type他來指定自定義的數據源類型,比如我們使用c3p0,包括dbcp等等,而Springboot能支持哪些數據源呢,自帶支持的就有這么多,tomcat的jdbc,還支持Hikari的jdbc,還有dbcp的BasicDataSource,包括dbcp2的數據源,我們也可以指定自己的,如果我們指定的數據源類型不是以上的,他就用這種來給我們創建數據源/*** Generic DataSource configuration.*/
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {@Beanpublic DataSource dataSource(DataSourceProperties properties) {return properties.initializeDataSourceBuilder().build();}}自定義數據源,自定義數據源類型,這里他有一個機制,如果你是自定義數據源的類型,數據源是怎么創建出來呢,/*** Initialize a {@link DataSourceBuilder} with the state of this instance.* @return a {@link DataSourceBuilder} initialized with the customizations defined on* this instance*/
public DataSourceBuilder initializeDataSourceBuilder() {return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName()).url(determineUrl()).username(determineUsername()).password(determinePassword());
}使用DataSourceBuilder來創建數據源的,Builder創建數據源的步驟呢,public DataSource build() {Class<? extends DataSource> type = getType();DataSource result = BeanUtils.instantiate(type);maybeGetDriverClassName();bind(result);return result;
}調用build方法來創建數據源,他就是用BeanUtils工具進行反射,并且綁定相關的屬性,利用反射創建相應type的數據源,并且綁定相關屬性,這里有一個DataSourceAutoConfiguration,數據源的自動配置,@Bean
@ConditionalOnMissingBean
public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,ApplicationContext applicationContext) {return new DataSourceInitializer(properties, applicationContext);
}DataSourceInitializer的作用是什么,DataSourceInitializer是ApplicationListener,它是一個監聽器,而這個ApplicationListener,我們在Spring注解版的時候,給大家有講過,大家可以去參考他的原理,我們就來說一下他的作用,這個作用就是兩處,我們直接參考這個類就行了,這個類上的解釋也看到,初始化的時候可以幫我們運行schema,/*** Bean to handle {@link DataSource} initialization by running {@literal schema-*.sql} on* {@link PostConstruct} and {@literal data-*.sql} SQL scripts on a* {@link DataSourceInitializedEvent}.** @author Dave Syer* @author Phillip Webb* @author Eddú Meléndez* @author Stephane Nicoll* @author Kazuki Shimizu* @since 1.1.0* @see DataSourceAutoConfiguration*/
class DataSourceInitializer implements ApplicationListener<DataSourceInitializedEvent> {包括data的sql文件,第一個叫@PostConstruct@PostConstruct
public void init() {if (!this.properties.isInitialize()) {logger.debug("Initialization disabled (not running DDL scripts)");return;}if (this.applicationContext.getBeanNamesForType(DataSource.class, false,false).length > 0) {this.dataSource = this.applicationContext.getBean(DataSource.class);}if (this.dataSource == null) {logger.debug("No DataSource found so not initializing");return;}runSchemaScripts();
}數據源剛創建好,創建好對象以后,要調用這個方法,這個方法他從容器中拿到數據源,拿到數據源以后runSchemaScripts,這是他的第一個作用,運行建表語句,我們把建表語句放到指定位置,人家就能夠執行了,還有一步叫onApplicationEvent,這就是我們的監聽器,在我們監聽到一個事件以后,調用這個方法@Override
public void onApplicationEvent(DataSourceInitializedEvent event) {if (!this.properties.isInitialize()) {logger.debug("Initialization disabled (not running data scripts)");return;}// NOTE the event can happen more than once and// the event datasource is not used hereif (!this.initialized) {runDataScripts();this.initialized = true;}
}這個方法還能runDataScripts,運行插入數據的語句,這樣我們把建表和插入數據的相關的SQL文件,放進來就行了,而它默認的規則是什么,默認只需要將文件命名為,如果是建表的就命名為schema-.sql,如果是數據的,那你就命名為data-*.sql這種形式的sql,就這么來命名就行了,就是這兩種文件,就是在Initializer里面運行的,正好我們有一個建表語句,來看我們能不能把相應的表創建出來,我們在跑建表語句的時候,那要先得到scripts,得到這個而文件,private List<Resource> getScripts(String propertyName, List<String> resources,String fallback) {if (resources != null) {return getResources(propertyName, resources, true);}String platform = this.properties.getPlatform();List<String> fallbackResources = new ArrayList<String>();fallbackResources.add("classpath*:" + fallback + "-" + platform + ".sql");fallbackResources.add("classpath*:" + fallback + ".sql");return getResources(propertyName, fallbackResources, false);
}/*** Platform to use in the DDL or DML scripts (e.g. schema-${platform}.sql or* data-${platform}.sql).*/
private String platform = "all";spring.datasource.schema= # Schema (DDL) script resource references.spring.datasource.schema=classpath:department.sqlJdbcTemplateAutoConfiguration,如果有數據源的情況下,他還會給我們容器中添加一個JdbcTemplate@Bean
@Primary
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate() {return new JdbcTemplate(this.dataSource);
}@Bean
@Primary
@ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {return new NamedParameterJdbcTemplate(this.dataSource);
}這都是學Spring底層操作數據庫,自動配置了JdbcTemplate操作數據庫,我們要操作數據庫呢,我來寫一個最簡單的演示方法
注入JdbcTemplate,jdbcTemplate可以直接注入的http://localhost:8080/query
package com.learn.controller;import java.util.List;
import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class HelloController {@AutowiredJdbcTemplate jdbcTemplate;@ResponseBody@GetMapping("/query")public Map<String,Object> map(){List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from department");return list.get(0);}}
?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的SpringBoot_数据访问-JDBC自动配置原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot_数据访问-简介
- 下一篇: SpringBoot_数据访问-整合Dr