Spring中配置數據源的幾種方式 通過在JDBC驅動程式定義的數據源; 通過JNDI查找的數據源; 連接池的數據源; 使用JNDI數據源 Spring應用程式經常部署在Java EE應用伺服器中,例如Tomcat、JBoss。這些伺服器器允許你通過配置獲取數據源,這樣做的好處是數據源可以在應用之外 ...
Spring中配置數據源的幾種方式
- 通過在JDBC驅動程式定義的數據源;
- 通過JNDI查找的數據源;
- 連接池的數據源;
使用JNDI數據源
Spring應用程式經常部署在Java EE應用伺服器中,例如Tomcat、JBoss。這些伺服器器允許你通過配置獲取數據源,這樣做的好處是數據源可以在應用之外進行管理。另外,在應用伺服器中數據源通常都是以連接池的方式組織,從而具備更好的性能,並且還支持系統管理員對其進行熱切換。
對於Tomcat需要在tomcat/conf/context.xml中配置好連接信息,其中name指的是JNDI的名稱
<Resource auth="Container" driverClassName="oracle.jdbc.driver.OracleDriver" name="jdbc/dev" password="dev" type="javax.sql.DataSource" url="jdbc:oracle:thin:@127.0.0.1:1521/orcl" username="dev"/>
對於Sping應用來說需要手動配置
@Bean public JndiObjectFactoryBean dataSource() { JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean(); jndiObjectFactoryBean.setJndiName("jdbc/dev"); jndiObjectFactoryBean.setResourceRef(true); jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class); return jndiObjectFactoryBean; }
Spring boot中幫我們自動配置好了,只需要在application.properties中聲明指定jndiName就可以了。
spring.datasource.jndi-name=java:comp/env/jdbc/dev // 或者是 spring.datasource.jndi-name=jdbc/dev
因為Spring boot自帶web容器,因此JNDI方式只適用於將war發佈到獨立的web容器啟動的方式。
使用連接池的數據源
啥是連接池?
資料庫連接池是web容器(比如Tomcat)提供的一個資料庫連接管理的容器,連接池負責分配、管理和釋放資料庫連接,它允許應用程式重覆使用一個現有的資料庫連接,而不是再重新建立一個。
為什麼要用它?
資料庫連接是一種關鍵的有限的昂貴的資源,這一點在多用戶的網頁應用程式中體現得尤為突出。 一個資料庫連接對象均對應一個物理資料庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的性能低下。 資料庫連接池的解決方案是在應用程式啟動時建立足夠的資料庫連接,並講這些連接組成一個連接池(簡單說:在一個“池”里放了好多半成品的資料庫聯接對象),由應用程式動態地對池中的連接進行申請、使用和釋放。對於多於連接池中連接數的併發請求,應該在請求隊列中排隊等待。並且應用程式可以根據池中連接的使用率,動態增加或減少池中的連接數。 連接池技術儘可能多地重用了消耗記憶體地資源,大大節省了記憶體,提高了伺服器地服務效率,能夠支持更多的客戶服務。通過使用連接池,將大大提高程式運行效率,同時,我們可以通過其自身的管理機制來監視資料庫連接的數量、使用情況等。
在Spring Boot中怎麼用?
配置連接池參數
- 最小連接數:是連接池一直保持的資料庫連接,所以如果應用程式對資料庫連接的使用量不大,將會有大量的資料庫連接資源被浪費.
- 最大連接數:是連接池能申請的最大連接數,如果資料庫連接請求超過次數,後面的資料庫連接請求將被加入到等待隊列中,這會影響以後的資料庫操作
- 最大空閑時間: 超出這個時間,該連接將被銷毀
- 獲取連接超時時間: 超出時間程式將會返回連接超時異常
- 超時重試連接次數: 超時後重新連接的次數
Spring Boot2.0預設使用HikariCP連接池得到數據源
spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.username=sa spring.datasource.password= spring.datasource.hikari.maximumPoolSize=5 spring.datasource.hikari.minimumIdle=5 spring.datasource.hikari.idleTimeout=600000 spring.datasource.hikari.connectionTimeout=30000 spring.datasource.hikari.maxLifetime=1800000
這樣就搞定了,Spring Boot幫我們把數據源創建、事務管理、JdbcTemplate創建都搞定了。
多數據源配置
在Sring boot中配置多數據源需要寫多套配置,例如創建兩個數據源
foo.datasource.url=jdbc:h2:mem:foo foo.datasource.username=sa foo.datasource.password= bar.datasource.url=jdbc:h2:mem:bar bar.datasource.username=sa bar.datasource.password=
分別用Java Config 為不同的配置創建數據源Bean。
首先讓Spring boot取消自動配置
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class})
然後手動配置DataSource和TransactionManager,@Primary註解指明當有兩個類實現同一介面的時候該採用哪個實現類進行@Autowried,另外可以在實現類上用@Qualifier("className")指定名稱,後面@Autowried的時候也用@Qualifier指定註入哪個類。
@Configuration @Slf4j public class DataSourceConfig { @Bean @ConfigurationProperties("foo.datasource") public DataSourceProperties fooDataSourceProperties() { return new DataSourceProperties(); } @Bean @Primary public DataSource fooDataSource() { DataSourceProperties dataSourceProperties = fooDataSourceProperties(); log.info("foo datasource: {}", dataSourceProperties.getUrl()); return dataSourceProperties.initializeDataSourceBuilder().build(); } @Bean JdbcTemplate fooJdbcTemplate(@Qualifier("fooDataSource")DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean @Resource public PlatformTransactionManager fooTxManager(DataSource fooDataSource) { return new DataSourceTransactionManager(fooDataSource); } @Bean @ConfigurationProperties("bar.datasource") public DataSourceProperties barDataSourceProperties() { return new DataSourceProperties(); } @Bean public DataSource barDataSource() { DataSourceProperties dataSourceProperties = barDataSourceProperties(); log.info("bar datasource: {}", dataSourceProperties.getUrl()); return dataSourceProperties.initializeDataSourceBuilder().build(); } @Primary @Bean JdbcTemplate barJdbcTemplate(@Qualifier("barDataSource")DataSource dataSource) { return new JdbcTemplate(dataSource); } @Bean @Resource public PlatformTransactionManager barTxManager(DataSource barDataSource) { return new DataSourceTransactionManager(barDataSource); } }
到此我們可以使用DataSource了
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, JdbcTemplateAutoConfiguration.class}) @Slf4j public class MultiDataSourceApplication implements CommandLineRunner { @Autowired private DataSource dataSource; @Autowired @Qualifier("barDataSource") private DataSource barDataSource; @Autowired @Qualifier("fooJdbcTemplate") private JdbcTemplate fooJdbcTemplate; @Autowired @Qualifier("barJdbcTemplate") private JdbcTemplate barJdbcTemplate; public static void main(String[] args) { SpringApplication.run(MultiDataSourceApplication.class, args); } @Override public void run(String... args) throws Exception { showConnection(); } private void showConnection() throws SQLException { log.info("fooDataSource數據源: " + dataSource.toString()); log.info("fooJdbcTemplate: " + fooJdbcTemplate.toString()); log.info("barDataSource數據源: " + barDataSource.toString()); log.info("barJdbcTemplate: " + barJdbcTemplate.toString()); } }