提供了一種物件與關聯映射工具來管理 Java 應用中的關係資料,用極簡的代碼就能實現對資料庫的操作訪問,實現了多資料庫的設定, EP 16 增加了相依套件及範例,並透過 JUnit 5 單元測試來驗證產出結果。
Table of Contents
Toggle前言
MariaDB 是一個關聯式資料庫,由 MySQL 原始開發人員建立的一個分支,源於與 MySQL 被 Oracle 收購有關的擔憂。它支援小資料處理任務和企業需求, 目標是成為 MySQL 的替代品。.
Spring Data JPA
檔案目錄
./
+- build.gradle
+- src
+- main
+- resources
| +- application.properties
+- java
| +- org
| +- ruoxue
| +- spring_boot_168
| +- config
| +- LogDataSourceConfig.java
Gradle
build.gradle
增加 Spring Boot Starter Data JPA 。
增加 MariaDB Java Client 。
修改完後,點右鍵,Gradle -> Refresh Gradle Project 。
buildscript {
group 'org.ruoxue.spring-boot-168'
version = '0.0.1-SNAPSHOT'
ext {
springBootVersion = '2.1.7.RELEASE'
mariadbJavaClientVersion = '2.4.3'
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}"
implementation "org.mariadb.jdbc:mariadb-java-client:${mariadbJavaClientVersion}"
}
設定 Multiple Databases
application.properties
增加 Datasource 設定。
spring.datasource.hikari.jdbc-url=jdbc:mariadb://127.0.0.1:3306/spring_boot_168
spring.datasource.hikari.username=root
spring.datasource.hikari.password=1111
spring.datasource.hikari.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.hikari.pool-name=primaryDatabase
spring.datasource.hikari.maximum-pool-size=100
spring.datasource.hikari.minimum-idle=8
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.max-lifetime=27800000
spring.datasource.hikari.auto-commit=false
spring.datasource.log.hikari.jdbc-url=jdbc:mariadb://127.0.0.1:3306/spring_boot_168_log
spring.datasource.log.hikari.username=root
spring.datasource.log.hikari.password=1111
spring.datasource.log.hikari.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.log.hikari.pool-name=logDatabase
spring.datasource.log.hikari.maximum-pool-size=100
spring.datasource.log.hikari.minimum-idle=8
spring.datasource.log.hikari.idle-timeout=600000
spring.datasource.log.hikari.connection-timeout=60000
spring.datasource.log.hikari.max-lifetime=27800000
spring.datasource.log.hikari.auto-commit=false
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.jdbc.batch_size=10
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates =true
LogDataSourceConfig.java
新增檔案。
package org.ruoxue.spring_boot_168.config;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "logEntityManagerFactory", //
transactionManagerRef = "logTransactionManager", //
basePackages = { //
"org.ruoxue.spring_boot_168.sso.account_log.repository", //
})
@Configuration
@Slf4j
public class LogDataSourceConfig {
@Autowired
private HibernateProperties hibernateProperties;
@Autowired
private JpaProperties jpaProperties;
@Bean(name = "logDataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.log.hikari")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name = "logHikariConfig")
@ConfigurationProperties(prefix = "spring.datasource.log.hikari")
public HikariConfig hikariConfig() {
HikariConfig hikariConfig = new HikariConfig();
return hikariConfig;
}
@Bean(name = "logDataSource")
public DataSource dataSource(@Qualifier("logHikariConfig") HikariConfig hikariConfig) {
log.info("poolName: " + hikariConfig.getPoolName());
log.info("jdbcUrl: " + hikariConfig.getJdbcUrl());
log.info("username: " + hikariConfig.getUsername());
log.info("driverClassName: " + hikariConfig.getDriverClassName());
log.info("maximumPoolSize: " + hikariConfig.getMaximumPoolSize());
log.info("connectionTimeout: " + hikariConfig.getConnectionTimeout());
log.info("maxLifetime: " + hikariConfig.getMaxLifetime());
log.info("autoCommit: " + hikariConfig.isAutoCommit());
log.info("jpaProperties: " + jpaProperties.getProperties());
DataSource dataSource = new HikariDataSource(hikariConfig);
return dataSource;
}
@Bean(name = "logEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("logDataSource") DataSource dataSource) {
Map<String, Object> properties = hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(),
new HibernateSettings());
return builder.dataSource(dataSource)//
.packages( //
"org.ruoxue.spring_boot_168.sso.account_log.model"//
).persistenceUnit("logDatabase")//
.properties(properties)//
.build();
}
@Bean(name = "logTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("logEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
@Bean(name = "logJdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("logDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
測試
LogDataSourceConfigTest.java
新增單元測試,驗證是否符合預期 。
package org.ruoxue.spring_boot_168.config;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.ruoxue.spring_boot_168.Application;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.zaxxer.hikari.HikariConfig;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = Application.class)
public class LogDataSourceConfigTest {
@Autowired
private LogDataSourceConfig config;
@Test
public void config() {
assertNotNull(config);
HikariConfig hikariConfig = config.hikariConfig();
String jdbcUrl = hikariConfig.getJdbcUrl();
assertEquals("jdbc:mariadb://127.0.0.1:3306/spring_boot_168_log", jdbcUrl);
}
}
config
測試方法上點右鍵執行 Run As -> JUnit Test ,查看 console 。
2022-05-25T21:29:16.543+0800 [main] INFO dataSource:65 - poolName: primaryDatabase
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:66 - jdbcUrl: jdbc:mariadb://127.0.0.1:3306/spring_boot_168
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:67 - username: root
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:68 - driverClassName: org.mariadb.jdbc.Driver
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:69 - maximumPoolSize: 100
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:70 - connectionTimeout: 60000
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:71 - maxLifetime: 27800000
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:72 - autoCommit: false
2022-05-25T21:29:16.559+0800 [main] INFO dataSource:73 - jpaProperties: {hibernate.jdbc.batch_versioned_data=true, hibernate.order_updates=true, hibernate.jdbc.batch_size=10, hibernate.order_inserts=true}
2022-05-25T21:29:16.559+0800 [main] INFO HikariDataSource#<init>:80 - primaryDatabase - Starting...
2022-05-25T21:29:16.606+0800 [main] INFO HikariDataSource#<init>:82 - primaryDatabase - Start completed.
2022-05-25T21:29:16.640+0800 [main] INFO dataSource:61 - poolName: logDatabase
2022-05-25T21:29:16.640+0800 [main] INFO dataSource:62 - jdbcUrl: jdbc:mariadb://127.0.0.1:3306/spring_boot_168_log
2022-05-25T21:29:16.640+0800 [main] INFO dataSource:63 - username: root
2022-05-25T21:29:16.641+0800 [main] INFO dataSource:64 - driverClassName: org.mariadb.jdbc.Driver
2022-05-25T21:29:16.641+0800 [main] INFO dataSource:65 - maximumPoolSize: 100
2022-05-25T21:29:16.641+0800 [main] INFO dataSource:66 - connectionTimeout: 60000
2022-05-25T21:29:16.642+0800 [main] INFO dataSource:67 - maxLifetime: 27800000
2022-05-25T21:29:16.642+0800 [main] INFO dataSource:68 - autoCommit: false
2022-05-25T21:29:16.642+0800 [main] INFO dataSource:69 - jpaProperties: {hibernate.jdbc.batch_versioned_data=true, hibernate.order_updates=true, hibernate.jdbc.batch_size=10, hibernate.order_inserts=true}
2022-05-25T21:29:16.643+0800 [main] INFO HikariDataSource#<init>:80 - logDatabase - Starting...
2022-05-25T21:29:16.645+0800 [main] INFO HikariDataSource#<init>:82 - logDatabase - Start completed.
心得分享
實現多資料庫的連線池,設定連線池最大與最小連線數限制,及取得連線逾時,閒置逾時等功能,讓資料庫連線更有效率,節省系統資源的耗用。