创建工程目录
mkdir SpringBootIntergrationDemo
cd SpringBootIntergrationDemo
gradle init # 初始化为gradle工程,选择application -> Kotlin -> only one application project -> groovy
或直接通过Spring Initializr
创建工程。
添加依赖
编辑build.gradle
,添加依赖:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Kotlin application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.7/userguide/building_java_projects.html
*/
plugins {
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
id 'org.jetbrains.kotlin.jvm' version '1.3.72'
// SpringBoot依赖
id 'org.springframework.boot' version '2.3.4.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
// Apply the application plugin to add support for building a CLI application in Java.
// id 'application'
}
group = "top.wteng"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11 // jdk11
repositories {
// Use JCenter for resolving dependencies.
// jcenter()
// 使用阿里镜像
repositories {
maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral()
}
}
dependencies {
// Align versions of all Kotlin components
implementation platform('org.jetbrains.kotlin:kotlin-bom')
// Use the Kotlin JDK 8 standard library.
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
//反射
implementation 'org.jetbrains.kotlin:kotlin-reflect'
// This dependency is used by the application.
implementation 'com.google.guava:guava:29.0-jre'
// spintboot相关
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
//jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// h2
implementation 'com.h2database:h2:1.4.200'
// spingboot集成测试
testImplementation ('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
tasks.withType(Test).all {
useJUnitPlatform()
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "11" // kotlin编译版本
}
}
配置数据源
这里配置两个数据源,为测试方便,直接使用h2
数据库。
配置yaml
编辑`application.yaml
:
spring:
datasource:
primary: # 主数据源
platform: h2
url: jdbc:h2:mem:primary
username: sa
password:
schema: classpath:schema.sql
data: classpath:data.sql
second: # 第二数据源
platform: h2
url: jdbc:h2:mem:second
username: sa
password:
schema: classpath:schema.sql
data: classpath:data.sql
jpa: # jpa配置
primary: # 主数据源jpa
generate-ddl: false
show-sql: false
hibernate: none
second: # 第二数据源jpa
generate-ddl: false
show-sql: false
hibernate: none
h2: # h2数据库配置
console:
path: /h2-console
enabled: true
settings:
web-allow-others: true # 允许web登录控制台
配置数据源
编写数据源配置,要注意的是必须有一个应用@Primary
注解的主数据源
package top.wteng.springboot.intergration.configuration
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
import javax.sql.DataSource
@Configuration
open class DataSourceConfiguration {
@Primary
@Bean(name = ["primaryDataSourceProperties"])
@ConfigurationProperties(prefix = "spring.datasource.primary") // 数据源的配置前缀
open fun primaryDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Primary
@Bean(name = ["primaryDataSource"])
open fun primaryDataSource(@Qualifier("primaryDataSourceProperties") properties: DataSourceProperties): DataSource {
return properties.initializeDataSourceBuilder().build()
}
@Bean(name = ["secondDataSourceProperties"])
@ConfigurationProperties(prefix = "spring.datasource.second")
open fun secondDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean(name = ["secondDataSource"])
open fun secondDataSource(@Qualifier("secondDataSourceProperties") properties: DataSourceProperties): DataSource {
return properties.initializeDataSourceBuilder().build()
}
}
配置JPA
编写jpa
配置,因为有两个数据源,所以编写两个配置,配置目的是要指定每个数据源扫描实体的包路径,每个数据源扫描特定包目录下的实体,生成相应的bean
。
第一个数据源配置:
package top.wteng.springboot.intergration.configuration
import org.springframework.beans.factory.annotation.Qualifier
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.context.annotation.Primary
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.orm.jpa.JpaTransactionManager
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.transaction.annotation.EnableTransactionManagement
import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.sql.DataSource
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["top.wteng.springboot.intergration.repository.primary"], // 扫描的包名称,只扫描该包下的repository定义
entityManagerFactoryRef = "primaryEntityManagerFactory", // 实体管理bean名称
transactionManagerRef = "primaryTransactionManager" // 事务bean名称
)
open class PrimaryJpaConfiguration {
@Primary // 指定为主数据源
@Bean(name = ["primaryJpaProperties"])
@ConfigurationProperties(prefix = "spring.jpa.primary") // 配置前缀
open fun primaryJpaProperties(): JpaProperties {
return JpaProperties()
}
@Primary
@Bean(name = ["primaryEntityManagerFactory"])
open fun primaryEntityManagerFactory(
@Qualifier("primaryDataSource") primaryDataSource: DataSource, // 使用主数据源
@Qualifier("primaryJpaProperties") jpaProperties: JpaProperties, // JPA配置属性
builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
return builder.dataSource(primaryDataSource)
.properties(jpaProperties.properties)
.packages("top.wteng.springboot.intergration.entity.primary") // 实体包路径,只扫描该包下的实体定义
.persistenceUnit("primaryPersistenceUnit")
.build()
}
@Primary
@Bean(name = ["primaryEntityManager"])
open fun primaryEntityManager(@Qualifier("primaryEntityManagerFactory") managerFactory: EntityManagerFactory): EntityManager {
return managerFactory.createEntityManager()
}
@Primary
@Bean(name = ["primaryTransactionManager"])
open fun primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") factory: EntityManagerFactory): JpaTransactionManager {
return JpaTransactionManager(factory)
}
}
第二个数据源配置如下,配置方式同主数据源一致,只是不必应用primary
注解:
package top.wteng.springboot.intergration.configuration
import org.springframework.beans.factory.annotation.Qualifier
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.orm.jpa.JpaTransactionManager
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.transaction.annotation.EnableTransactionManagement
import javax.persistence.EntityManager
import javax.persistence.EntityManagerFactory
import javax.sql.DataSource
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["top.wteng.springboot.intergration.repository.second"], // 扫描的包名称
entityManagerFactoryRef = "secondEntityManagerFactory", // 实体管理bean名称
transactionManagerRef = "secondTransactionManager" // 事务bean名称
)
open class SecondJpaConfiguration {
@Bean(name = ["secondJpaProperties"])
@ConfigurationProperties(prefix = "spring.jpa.second")
open fun secondJpaProperties(): JpaProperties {
return JpaProperties()
}
@Bean(name = ["secondEntityManagerFactory"])
open fun secondEntityManagerFactory(
@Qualifier("secondDataSource") secondDataSource: DataSource,
@Qualifier("secondJpaProperties") jpaProperties: JpaProperties,
builder: EntityManagerFactoryBuilder): LocalContainerEntityManagerFactoryBean {
return builder.dataSource(secondDataSource)
.properties(jpaProperties.properties)
.packages("top.wteng.springboot.intergration.entity.second") // 实体包路径
.persistenceUnit("secondPersistenceUnit")
.build()
}
@Bean(name = ["secondEntityManager"])
open fun secondEntityManager(@Qualifier("secondEntityManagerFactory") managerFactory: EntityManagerFactory): EntityManager {
return managerFactory.createEntityManager()
}
@Bean(name = ["secondTransactionManager"])
open fun secondTransactionManager(@Qualifier("secondEntityManagerFactory") factory: EntityManagerFactory): JpaTransactionManager {
return JpaTransactionManager(factory)
}
}
经过以上数据源配置,数据源primary
会扫描op.wteng.springboot.intergration.entity.primary
下的实体定义与top.wteng.springboot.intergration.repository.primary
下的repository
定义,操作相关实体会应用主数据源,而第二数据源会扫描top.wteng.springboot.intergration.entity.second
下的实体与top.wteng.springboot.intergration.repository.second
下的repository
定义,操作相关实体会应用第二数据源。
根据具体业务存储需求将不同的实体及repository
定义到相应的包下即可,定义及使用同单数据源一致。