關(guān)鍵詞:mysql 達夢/dameng jpa 多數(shù)據(jù)源
版本信息/主要引包信息
spring boot:2.1.17.RELEASE
mysql驅(qū)動:8.0.21(跟隨boot版本)
達夢驅(qū)動:8.1.2.192
lombok:1.18.12(跟隨boot版本)
背景概述
- 以mysql為主數(shù)據(jù)源,達夢為第二數(shù)據(jù)源方式配置
- 適用于舊項目二次開發(fā)接入達夢數(shù)據(jù)庫或基于通用二方/三方包做業(yè)務(wù)擴展等場景
- 將以不同包路徑方式綁定不同數(shù)據(jù)源,以便擴展
代碼示例
- 其中,primary為主數(shù)據(jù)源,second為第二數(shù)據(jù)源
引包部分(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org</groupId>
<artifactId>test-jpa-tra</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test-jpa-tra</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.1.17.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- 數(shù)據(jù)庫驅(qū)動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.2.192</version>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmDialect-for-hibernate5.3</artifactId>
<version>8.1.2.192</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
實體部分(Entity)
主數(shù)據(jù)源:
package org.test.data.entity.primary;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "test")
public class Test {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
第二數(shù)據(jù)源:
package org.test.data.entity.second;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "test2")
public class Test2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
}
數(shù)據(jù)庫接口部分(Repository)
主數(shù)據(jù)源:
package org.test.dao.primary;
import org.springframework.stereotype.Repository;
import org.test.data.entity.primary.Test;
import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface TestRepository extends JpaRepository<Test, Integer> {
}
第二數(shù)據(jù)源:
package org.test.dao.second;
import org.springframework.stereotype.Repository;
import org.test.data.entity.second.Test2;
import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface TestRepository2 extends JpaRepository<Test2, Integer> {
}
服務(wù)接口部分(Service)
此處略,可按實際項目關(guān)聯(lián),服務(wù)部分可無需區(qū)分包路徑
配置部分(Configuration)
此處將配置數(shù)據(jù)庫配置讀取、數(shù)據(jù)源、EntityManager構(gòu)造工廠以及事務(wù)管理器
主數(shù)據(jù)源:
package org.test.property.config;
import java.util.HashMap;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
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.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@EnableTransactionManagement // 開啟事務(wù)
@EnableJpaRepositories(basePackages = { "org.test.dao.primary" },
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager"
)
public class TestPrimaryDataSourceConfig {
/**
* 指定 primary 數(shù)據(jù)源的 dataSource 配置
*
* @return primary 數(shù)據(jù)源配置
*/
@Primary
@Bean(name = "primaryDataSourceProperties")
@ConfigurationProperties("spring.datasource.primary")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
/**
* 可以選擇不同的數(shù)據(jù)源,這?使? HikariDataSource,創(chuàng)建數(shù)據(jù)源
*
* @param primaryDataSourceProperties
* 數(shù)據(jù)源配置
* @return primary 數(shù)據(jù)源
*/
@Primary
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari.primary") // 配置
// primary
// 數(shù)據(jù)源所?的
// hikari
// 配置
// key
// 的前綴
public DataSource dataSource(
@Qualifier("primaryDataSourceProperties") DataSourceProperties primaryDataSourceProperties) {
HikariDataSource dataSource = primaryDataSourceProperties.initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
if (StringUtils.hasText(primaryDataSourceProperties.getName())) {
dataSource.setPoolName(primaryDataSourceProperties.getName());
}
return dataSource;
}
/**
* 配置 primary 數(shù)據(jù)源的 entityManagerFactory 命名為
* primaryEntityManagerFactory,?來對實體進??些操作
*
* @param builder
* 構(gòu)建器
* @param primaryDataSource
* primary 數(shù)據(jù)源
* @return primary 實體管理工廠
*/
@Primary
@Bean(name = "primaryEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("primaryDataSource") DataSource primaryDataSource) {
final HashMap<String, Object> hibernateProperties = new HashMap<String, Object>();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
return builder.dataSource(primaryDataSource).properties(hibernateProperties)
// primary 數(shù)據(jù)的實體所在的路徑
.packages("org.test.data.entity.primary")
// persistenceUnit 的名字采? primary
.persistenceUnit("primary").build();
}
/**
* 配置 primary 數(shù)據(jù)源的事務(wù)管理者,命名為 primaryTransactionManager 依賴
* primaryEntityManagerFactory
*
* @param primaryEntityManagerFactory
* primary 實體管理工廠
* @return primary 事務(wù)管理者
*/
@Primary
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("primaryEntityManagerFactory") EntityManagerFactory primaryEntityManagerFactory) {
return new JpaTransactionManager(primaryEntityManagerFactory);
}
}
第二數(shù)據(jù)源:
package org.test.property.config;
import java.util.HashMap;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
@EnableTransactionManagement // 開啟事務(wù)
@EnableJpaRepositories( // 利? EnableJpaRepositories 配置哪些包下?的 Repositories,采?哪個
// EntityManagerFactory 和哪個 TransactionManagement
basePackages = { "org.test.dao.second" },
entityManagerFactoryRef = "secondEntityManagerFactory",
transactionManagerRef = "secondTransactionManager"
)
public class TestSecondDataSourceConfig {
/**
* 指定 second 數(shù)據(jù)源的 dataSource 配置
*
* @return second 數(shù)據(jù)源配置
*/
@Bean(name = "secondDataSourceProperties")
// @Qualifier(value = "secondDataSourceProperties")
@ConfigurationProperties("spring.datasource.second") // second 數(shù)據(jù)源的配置前綴采?
// spring.datasource.second
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
/**
* 可以選擇不同的數(shù)據(jù)源,這?使? HikariDataSource,創(chuàng)建數(shù)據(jù)源
*
* @param secondDataSourceProperties
* 數(shù)據(jù)源配置
* @return second 數(shù)據(jù)源
*/
@Bean(name = "secondDataSource")
// @Qualifier(value = "secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.hikari.second") // 配置
// second
// 數(shù)據(jù)源所?的
// hikari
// 配置
// key
// 的前綴
public DataSource dataSource() {
DataSourceProperties secondDataSourceProperties = secondDataSourceProperties();
HikariDataSource dataSource = secondDataSourceProperties.initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
if (StringUtils.hasText(secondDataSourceProperties.getName())) {
dataSource.setPoolName(secondDataSourceProperties.getName());
}
return dataSource;
}
/**
* 配置 second 數(shù)據(jù)源的 entityManagerFactory 命名為
* secondEntityManagerFactory,?來對實體進??些操作
*
* @param builder
* 構(gòu)建器
* @param secondDataSource
* second 數(shù)據(jù)源
* @return second 實體管理工廠
*/
@Bean(name = "secondEntityManagerFactory")
// @Qualifier(value = "secondEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
final HashMap<String, Object> hibernateProperties = new HashMap<String, Object>();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.DmDialect");
return builder.dataSource(dataSource()).properties(hibernateProperties)
// second 數(shù)據(jù)的實體所在的路徑
.packages("org.test.data.entity.second")
// persistenceUnit 的名字采? second
.persistenceUnit("second").build();
}
/**
* 配置 second 數(shù)據(jù)源的事務(wù)管理者,命名為 secondTransactionManager 依賴
* secondEntityManagerFactory
*
* @param secondEntityManagerFactory
* second 實體管理工廠
* @return second 事務(wù)管理者
*/
@Bean(name = "secondTransactionManager")
// @Qualifier(value = "")
public PlatformTransactionManager transactionManager(
@Qualifier("secondEntityManagerFactory") EntityManagerFactory secondEntityManagerFactory) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
}
配置文件部分(application.properties)
如需更為yml,可自行轉(zhuǎn)換。
其中數(shù)據(jù)庫連接池為觀察效果用,可根據(jù)實際自行配置
#############################################
#######jpa setting
#############################################
#JPA Configuration:
# Show or not log for each sql query
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
# 主數(shù)據(jù)源配置
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.primary.url=
spring.datasource.primary.username=
spring.datasource.primary.password=
# 主數(shù)據(jù)源連接池配置(主要為觀察多數(shù)據(jù)源配置效果,可按實際配置或不配置)
# spring.datasource.hikari.primary.pool-name=jpa-hikari-pool-primary
# spring.datasource.hikari.primary.max-lifetime=900000
# spring.datasource.hikari.primary.maximum-pool-size=8
spring.datasource.second.driver-class-name=dm.jdbc.driver.DmDriver
spring.datasource.second.url=
spring.datasource.second.username=
spring.datasource.second.password=
# 第二數(shù)據(jù)源連接池配置(主要為觀察多數(shù)據(jù)源配置效果,可按實際配置或不配置)
# spring.datasource.hikari.second.pool-name=jpa-hikari-pool-second
# spring.datasource.hikari.second.max-lifetime=500000
# spring.datasource.hikari.second.maximum-pool-size=6
Controller部分(測試)
此為測試效果用,不推薦直接在controller層調(diào)用dao層寫法。
package org.test.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.test.data.entity.primary.Test;
import org.test.service.TestService;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestRepository testRepository;
@Autowired
private TestRepository2 testRepository2;
@GetMapping
public String test(String name) {
testRepository.save(new Test(null, name));
testRepository2.save(new Test2(null, name));
return "ok";
}
}
至此,便完成全部配置!
可能碰見的問題
1. 報語法不匹配/不支持問題“org.hibernate.HibernateException:對DialectResolutionInfo的訪問在’hibernate.dialect’未設(shè)置時不能為空”
在EntityManager工廠配置LocalContainerEntityManagerFactoryBean中添加方言指定:
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.DmDialect");
詳情可查看**配置部分(Configuration)**中TestSecondDataSourceConfig相關(guān)代碼。
參考文章:使用多個數(shù)據(jù)源時,Spring boot Hibernate錯誤“當“Hibernate.dialent”未設(shè)置時,對方言解析信息的訪問不能為null” - 一點教程
2. 報“僅當指定列列表,且SET IDENTITY_INSERT為ON時,才能對自增列賦值”問題
- 在版本8.1.1.49中,可通過將主鍵字段序列設(shè)置為
@GeneratedValue(strategy = GenerationType.AUTO)
解決 - 在版本8.1.2.192中,該問題已被解決。注意,新版本驅(qū)動更改了artifactId,詳情如下:
舊:
<dependency>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmDialect-for-hibernate5.3</artifactId>
<version>8.1.1.49</version>
</dependency>
新:
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.2.192</version>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmDialect-for-hibernate5.3</artifactId>
<version>8.1.2.192</version>
</dependency>
3. 啟動時報“org.hibernate.engine.jdbc.spi.TypeInfo : HHH000362: Unable to retrieve type info result set : dm.jdbc.driver.DMException: 第 1 行, 第 270 列[AUTO_INCREMENT]附近出現(xiàn)錯誤”問題
解決方法如問題2解決方法2即可。文章來源:http://www.zghlxwxcb.cn/news/detail-753065.html
參考文章
Spring Data JPA 之 多數(shù)據(jù)源配置_jpa 多數(shù)據(jù)源_曾小二的禿頭之路的博客-CSDN博客
使用多個數(shù)據(jù)源時,Spring boot Hibernate錯誤“當“Hibernate.dialent”未設(shè)置時,對方言解析信息的訪問不能為null” - 一點教程
spring boot mysql8 遷移到達夢報錯[AUTO_INCREMENT]附近出現(xiàn)錯誤_wdd668的博客-CSDN博客
dm.jdbc.driver.DMException: 第 1 行, 第 270 列[AUTO_INCREMENT]附近出現(xiàn)錯誤:語法分析出錯 | 達夢技術(shù)社區(qū)文章來源地址http://www.zghlxwxcb.cn/news/detail-753065.html
到了這里,關(guān)于spring boot下基于spring data jpa配置mysql+達夢多數(shù)據(jù)源(以不同包路徑方式,mysql為主數(shù)據(jù)源)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!