Springboot配置doris連接的實(shí)現(xiàn)示例
一. 使用 druid 連接池
因?yàn)?Doris 的前端(FE)兼容了 MySQL 協(xié)議,可以像連 MySQL 一樣連 Doris。這是 Doris 的一個(gè)核心設(shè)計(jì)特性,目的是方便接入、簡(jiǎn)化生態(tài)兼容。
首先需要引入 pom 依賴:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.1</version>
</dependency>
在springboot 的yml文件中配置:
spring:
datasource:
url: jdbc:mysql://192.168.1.111:9030/database_test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&maxReconnects=3
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 20 # 初始化時(shí)預(yù)創(chuàng)建的連接數(shù)
min-idle: 20 #最低 保持空閑的連接數(shù)
max-active: 200 # 最大連接池?cái)?shù)量
max-wait: 30000 # 連接池最大允許等待的時(shí)間(單位:毫秒)
validation-query: SELECT 1 # 驗(yàn)證連接是否有效
test-while-idle: true # 在連接池空閑時(shí)是否驗(yàn)證連接的有效性
test-on-borrow: true # 在從連接池中借用連接時(shí)是否驗(yàn)證連接的有效性
test-on-return: false # 在連接被歸還到連接池時(shí)是否驗(yàn)證連接的有效性
time-between-eviction-runs-millis: 30000 # 空閑連接回收的頻率(多久進(jìn)行一次檢查),單位為毫秒
min-evictable-idle-time-millis: 300000 # 空閑超過(guò)多長(zhǎng)時(shí)間后在下次檢查時(shí)會(huì)被回收,單位為毫秒
max-evictable-idle-time-millis: 600000 # 最大空閑時(shí)間的上限, 超過(guò)被強(qiáng)制回收
keep-alive: true # 主動(dòng)?;钸B接,避免網(wǎng)絡(luò)層斷鏈
phy-timeout-millis: 1800000 # 物理連接的 最大空閑時(shí)間,單位是毫秒。
remove-abandoned: true # 指定時(shí)間內(nèi)沒(méi)有被正常釋放(例如沒(méi)有及時(shí)關(guān)閉),連接池會(huì)主動(dòng)回收這個(gè)連接。
remove-abandoned-timeout: 300 # 連接被視為廢棄的超時(shí)時(shí)間,單位為秒。
二.多數(shù)據(jù)源配置 doris 連接
有的時(shí)候我們需要連接多數(shù)據(jù)源, 比如要同時(shí)連接 mysql 和 doris, 這時(shí)候我們就要進(jìn)行一些額外的配置。
1.配置文件配置
spring:
datasource:
mysql: # mysql 配置
url: jdbc:mysql://192.168.1.111:3306/mysql_database_test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true
username: root
password: 654321
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
validation-query: SELECT 1
max-active: 10
min-idle: 2
initial-size: 2
doris: # doris配置
url: jdbc:mysql://192.168.1.111:9030/database_test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&autoReconnect=true&failOverReadOnly=false&maxReconnects=3
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 20 # 初始化時(shí)預(yù)創(chuàng)建的連接數(shù)
min-idle: 20 #最低 保持空閑的連接數(shù)
max-active: 200 # 最大連接池?cái)?shù)量
max-wait: 30000 # 連接池最大允許等待的時(shí)間(單位:毫秒)
validation-query: SELECT 1 # 驗(yàn)證連接是否有效
test-while-idle: true # 在連接池空閑時(shí)是否驗(yàn)證連接的有效性
test-on-borrow: true # 在從連接池中借用連接時(shí)是否驗(yàn)證連接的有效性
test-on-return: false # 在連接被歸還到連接池時(shí)是否驗(yàn)證連接的有效性
time-between-eviction-runs-millis: 30000 # 空閑連接回收的頻率(多久進(jìn)行一次檢查),單位為毫秒
min-evictable-idle-time-millis: 300000 # 空閑超過(guò)多長(zhǎng)時(shí)間后在下次檢查時(shí)會(huì)被回收,單位為毫秒
max-evictable-idle-time-millis: 600000 # 最大空閑時(shí)間的上限, 超過(guò)被強(qiáng)制回收
keep-alive: true # 主動(dòng)保活連接,避免網(wǎng)絡(luò)層斷鏈
phy-timeout-millis: 1800000 # 物理連接的 最大空閑時(shí)間,單位是毫秒。
remove-abandoned: true # 指定時(shí)間內(nèi)沒(méi)有被正常釋放(例如沒(méi)有及時(shí)關(guān)閉),連接池會(huì)主動(dòng)回收這個(gè)連接。
remove-abandoned-timeout: 300 # 連接被視為廢棄的超時(shí)時(shí)間,單位為秒。
spring.datasource下的 mysql 和 doris可以自己自定義, 因?yàn)椴还苡檬裁疵? 我們能需在java中進(jìn)行數(shù)據(jù)庫(kù)數(shù)據(jù)源配置。
2.doris 數(shù)據(jù)庫(kù)數(shù)據(jù)源配置:
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* doris 數(shù)據(jù)庫(kù)數(shù)據(jù)源配置
* 指定要掃描的 Mapper 接口包路徑(Doris用)
* 指定對(duì)應(yīng)的 SqlSessionFactory Bean 名稱
* @author HY
* @date 2025-06-23
*/
@Configuration
@MapperScan(basePackages = "com.ashen.test.mapper.doris" , sqlSessionFactoryRef = "dorisSqlSessionFactory")
public class DorisConfig {
/**
* mybatis xml 文件位置
*/
private static final String MYBATIS_LOCATION = "classpath*:mybatis/doris/*.xml";
/**
* 實(shí)體類文件位置
*/
private static final String TYPE_ALIASES_PACKAGE = "com.ashen.test.common.model.entity.doris.*";
/**
* 創(chuàng)建 Doris 數(shù)據(jù)源 Bean,注入名稱為 "dorisDataSource"
* @return
*/
@Bean("dorisDataSource")
@ConfigurationProperties(prefix = "spring.datasource.doris")
public DataSource getDb1DataSource(){
// 構(gòu)建數(shù)據(jù)源對(duì)象(默認(rèn)用的是 HikariDataSource, 這個(gè)需要注意)
// return DataSourceBuilder.create().build();
return new com.alibaba.druid.pool.DruidDataSource();
}
/**
* 創(chuàng)建 SqlSessionFactory Bean,供 MyBatis 使用,注入名為 "dorisSqlSessionFactory"
* @param dataSource 注入上面定義的 Doris 數(shù)據(jù)源
* @return
* @throws Exception
*/
@Bean("dorisSqlSessionFactory")
public SqlSessionFactory dorisSqlSessionFactory(@Qualifier("dorisDataSource") DataSource dataSource) throws Exception {
// 創(chuàng)建工廠 Bean
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
// 設(shè)置數(shù)據(jù)源
bean.setDataSource(dataSource);
// 加載 Mybatis XML 文件
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MYBATIS_LOCATION));
// 設(shè)置實(shí)體類包路徑,用于簡(jiǎn)化 XML 中類型的全路徑書(shū)寫
bean.setTypeAliasesPackage(TYPE_ALIASES_PACKAGE);
// 獲取 SqlSessionFactory 實(shí)例
return bean.getObject();
}
/**
* 創(chuàng)建 SqlSessionTemplate Bean(線程安全的 SqlSession 封裝)
* 用于執(zhí)行 SQL、提交/回滾事務(wù)等
* @param sqlSessionFactory
* @return
*/
@Bean("dorisSqlSessionTemplate")
public SqlSessionTemplate dorisSqlSessionTemplate(@Qualifier("dorisSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
// 創(chuàng)建并返回模板實(shí)例
return new SqlSessionTemplate(sqlSessionFactory);
}
}
3.msyql 數(shù)據(jù)庫(kù)數(shù)據(jù)源配置:
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* mysql 數(shù)據(jù)庫(kù)數(shù)據(jù)源配置
* 指定要掃描的 Mapper 接口包路徑(Mysql 用)
* 指定對(duì)應(yīng)的 SqlSessionFactory Bean 名稱
* @author HY
* @date 2025-06-23
*/
@Configuration
@MapperScan(basePackages = "com.ashen.test.mapper.mysql", sqlSessionFactoryRef = "mysqlSqlSessionFactory")
public class MysqlConfig {
/**
* mybatis xml 文件位置
*/
private static final String MYBATIS_LOCATION = "classpath*:mybatis/mysql/*.xml";
/**
* 實(shí)體類文件位置
*/
private static final String TYPE_ALIASES_PACKAGE = "com.ashen.test.common.model.entity.mysql.*";
/**
* 創(chuàng)建 MySQL 數(shù)據(jù)源對(duì)象
* 被 @Primary 標(biāo)記為主數(shù)據(jù)源,默認(rèn)注入優(yōu)先使用這個(gè)
* 從 application.yml 讀取以 spring.datasource.mysql 為前綴的屬性進(jìn)行綁定
*/
@Primary
@Bean(name="mysqlDataSource")
@ConfigurationProperties(prefix = "spring.datasource.mysql")
public DataSource mysqlDataSource() {
// 使用 DataSourceBuilder 構(gòu)建數(shù)據(jù)源,支持 HikariCP、Druid 等(取決于依賴)
// return DataSourceBuilder.create().build();
return new com.alibaba.druid.pool.DruidDataSource();
}
/**
* 創(chuàng)建 MySQL 對(duì)應(yīng)的 SqlSessionFactory,供 MyBatis 使用
* 指定數(shù)據(jù)源、Mapper XML 文件路徑、實(shí)體別名路徑
* @param dataSource 注入 mysqlDataSource
*/
@Primary
@Bean("mysqlSqlSessionFactory")
public SqlSessionFactory mysqlSqlSessionFactory(@Qualifier("mysqlDataSource") DataSource dataSource) throws Exception {
// 創(chuàng)建 SqlSessionFactoryBean(MyBatis 與 Spring 整合的橋梁)
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
// 設(shè)置數(shù)據(jù)源
bean.setDataSource(dataSource);
// 指定 MyBatis 的 mapper XML 文件路徑(如果不配會(huì)找不到 SQL 映射)
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MYBATIS_LOCATION));
// 設(shè)置實(shí)體類所在包,用于自動(dòng)生成別名
bean.setTypeAliasesPackage(TYPE_ALIASES_PACKAGE);
// 返回 SqlSessionFactory 實(shí)例
return bean.getObject();
}
/**
* 創(chuàng)建 MyBatis 的 SqlSessionTemplate(線程安全、Spring 管理的 SqlSession)
* 用于執(zhí)行 SQL 操作、事務(wù)管理等
* @param sqlSessionFactory 注入上一步創(chuàng)建的 SqlSessionFactory
*/
@Primary
@Bean("mysqlSqlSessionTemplate")
public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
// 用工廠創(chuàng)建出模板
return new SqlSessionTemplate(sqlSessionFactory);
}
}
注: 這里有個(gè)坑, 就是在 mysqlDataSource() 方法中, 必須顯示的返回 。
return new com.alibaba.druid.pool.DruidDataSource();
如果采用:
return DataSourceBuilder.create().build();
最終將默認(rèn)采用 Spring Boot 內(nèi)建的 Hikari 數(shù)據(jù)源模塊。
三.druid 狀態(tài)監(jiān)控
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class DruidMonitor {
@Lazy
@Autowired
private DruidDataSource dataSource;
// 每1分鐘輸出一次連接池的狀態(tài)
@Scheduled(fixedRate = 600000)
public void printDruidStats() {
System.out.println("活躍連接數(shù) : " + dataSource.getActiveCount());
System.out.println("空閑連接數(shù) : " + dataSource.getPoolingCount());
System.out.println("最大允許的活躍連接數(shù) : " + dataSource.getMaxActive());
System.out.println("連接池中獲取連接的最大等待時(shí)間 : " + dataSource.getMaxWait());
System.out.println("連接池創(chuàng)建過(guò)的連接總數(shù) : " + dataSource.getCreateCount());
System.out.println("已經(jīng)關(guān)閉的連接總數(shù) : " + dataSource.getCloseCount());
System.out.println("===================================");
}
}
四. 連接超時(shí)問(wèn)題
空閑連接超時(shí)后, 會(huì)被連接池回收, 當(dāng)再次使用該連接的時(shí)候, 會(huì)報(bào)連接已關(guān)閉的錯(cuò)誤, 這種情況并不常見(jiàn), 但是有時(shí)候又會(huì)突然出現(xiàn), 讓我們以為是配置上有問(wèn)題。
例如:
當(dāng)我們遇到需要從socket或者消息隊(duì)列中持續(xù)取數(shù)據(jù)時(shí), 經(jīng)常會(huì)在 while(true) 中接收消息并插入數(shù)據(jù)庫(kù), 如果我們將 @Transactional 放在 while(true) 之上的方法上, 那么整個(gè)事務(wù)周期內(nèi)都將使用同一個(gè) durid 連接, 如果長(zhǎng)時(shí)間未從遠(yuǎn)程消息隊(duì)列或者socket中獲取到數(shù)據(jù), 那么該連接就會(huì)被回收, 當(dāng)再次來(lái)到數(shù)據(jù)并寫庫(kù)時(shí), 就會(huì)報(bào)連接已關(guān)閉的錯(cuò)誤。
@Transactional(readOnly = false, rollbackFor = Exception.class)
public void insert() {
....
while(true){
testMapper.insert(param);
}
}
因此要注意: 不要將 @Transactional 加到需要長(zhǎng)時(shí)間運(yùn)行的方法之上。
而是將插入方法脫離出去, 如下:
public void insert() {
....
while(true){
testMapper.insertData(param);
}
}
@Transactional(readOnly = false, rollbackFor = Exception.class)
public void insertData() {
testMapper.insert(param);
}
到此這篇關(guān)于Springboot配置doris連接的文章就介紹到這了,更多相關(guān)Springboot doris連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 在SpringBoot下讀取自定義properties配置文件的方法
- Spring Boot 日志配置方法(超詳細(xì))
- SpringBoot + Spring Security 基本使用及個(gè)性化登錄配置詳解
- springboot如何讀取配置文件(application.yml)中的屬性值
- 詳解SpringBoot配置連接池
- SpringBoot獲取yml和properties配置文件的內(nèi)容
- spring boot Logging的配置以及使用詳解
- spring boot的maven配置依賴詳解
- spring boot開(kāi)發(fā)遇到坑之spring-boot-starter-web配置文件使用教程
相關(guān)文章
關(guān)于同一個(gè)service調(diào)用service本身的方法
這篇文章主要介紹了關(guān)于同一個(gè)service調(diào)用service本身的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Java8 LocalDateTime極簡(jiǎn)時(shí)間日期操作小結(jié)
這篇文章主要介紹了Java8-LocalDateTime極簡(jiǎn)時(shí)間日期操作整理,通過(guò)實(shí)例代碼給大家介紹了java8 LocalDateTime 格式化問(wèn)題,需要的朋友可以參考下2020-04-04
Spring Boot與Kotlin定時(shí)任務(wù)的示例(Scheduling Tasks)
這篇文章主要介紹了Spring Boot與Kotlin定時(shí)任務(wù)的示例(Scheduling Tasks),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
Java ArrayList 實(shí)現(xiàn)實(shí)例講解
ArrayList是基于數(shù)組實(shí)現(xiàn)的,是一個(gè)動(dòng)態(tài)數(shù)組,其容量能自動(dòng)增長(zhǎng),類似于C語(yǔ)言中的動(dòng)態(tài)申請(qǐng)內(nèi)存,動(dòng)態(tài)增長(zhǎng)內(nèi)存。這篇文章主要介紹了java ArrayList 實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-11-11
IDEA2020 Plugins不能用的解決辦法及Plugins 搜索不了插件的問(wèn)題
這篇文章主要介紹了IDEA2020 Plugins不能用的解決辦法,文中給大家介紹了Intellij IDEA 2020.1 的Plugins 搜索不了插件,連接超時(shí)的問(wèn)題,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-06-06

