SpringBoot+druid同时连接不同类型数据库及PageHelper支持多类型库查询分页功能
Posted Vashon_杨博程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot+druid同时连接不同类型数据库及PageHelper支持多类型库查询分页功能相关的知识,希望对你有一定的参考价值。
SpringBoot+druid同时连接不同类型数据库及PageHelper支持多类型库查询分页功能
例子及场景:最近使用SpringBoot+durid需要连接多个数据源:同时支持mysql、Oracle,遇到问题及处理方法总结如下:
一、SpringBoot+druid支持同时连接MySQL和Oracle
pom.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ywx</groupId>
<artifactId>springboot-bi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-bi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<mybatis.boot.version>1.3.2</mybatis.boot.version>
<druid.version>1.1.13</druid.version>
<poi.version>3.17</poi.version>
</properties>
<dependencies>
<!--SpringBoot Web容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot 拦截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--常用工具类 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>$mybatis.boot.version</version>
</dependency>
<!--阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>$druid.version</version>
</dependency>
<!-- oracle数据库驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.1.0</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- yml解析器 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>$poi.version</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注:oracle驱动包在maven仓库中找不到,需下载手动导入到maven仓库。
yml配置文件:
spring:
datasource:
druid:
datasource1:
url: jdbc:oracle:thin:@10.xx.xx.xx:1521:orcl
username: xxxx
password: xxxx
driverClassName: oracle.jdbc.OracleDriver
datasource2:
# 数据源开关/默认关闭
url: jdbc:oracle:thin:@10.xx.xx.xx:1521:orcl
username: xepacs
password: xxx
driverClassName: oracle.jdbc.driver.OracleDriver
datasource3:
url: jdbc:mysql://10.xx.xx.xx:3306/ecg
username: ecg
password: xxx
driverClassName: com.mysql.jdbc.Driver
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
statViewServlet:
enabled: true
url-pattern: /monitor/druid/*
filter:
stat:
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
数据源基本参数配置类:
package com.ywx.framework.config.properties;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* 数据源配置文件封装类.
*
* @author ybc
* @date 2019-06-25-10:17
*/
@Configuration
public class DruidProperties
@Value("$spring.datasource.druid.initialSize")
private int initialSize;
@Value("$spring.datasource.druid.minIdle")
private int minIdle;
@Value("$spring.datasource.druid.maxActive")
private int maxActive;
@Value("$spring.datasource.druid.maxWait")
private int maxWait;
@Value("$spring.datasource.druid.timeBetweenEvictionRunsMillis")
private int timeBetweenEvictionRunsMillis;
@Value("$spring.datasource.druid.minEvictableIdleTimeMillis")
private int minEvictableIdleTimeMillis;
@Value("$spring.datasource.druid.maxEvictableIdleTimeMillis")
private int maxEvictableIdleTimeMillis;
@Value("$spring.datasource.druid.validationQuery")
private String validationQuery;
@Value("$spring.datasource.druid.testWhileIdle")
private boolean testWhileIdle;
@Value("$spring.datasource.druid.testOnBorrow")
private boolean testOnBorrow;
@Value("$spring.datasource.druid.testOnReturn")
private boolean testOnReturn;
public DruidDataSource dataSource(DruidDataSource datasource)
/** 配置初始化大小、最小、最大 */
datasource.setInitialSize(initialSize);
datasource.setMaxActive(maxActive);
datasource.setMinIdle(minIdle);
/** 配置获取连接等待超时的时间 */
datasource.setMaxWait(maxWait);
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
/** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
/**
* 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
*/
datasource.setValidationQuery(validationQuery);
/** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
datasource.setTestWhileIdle(testWhileIdle);
/** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource.setTestOnBorrow(testOnBorrow);
/** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
datasource.setTestOnReturn(testOnReturn);
return datasource;
数据源配置类:
package com.ywx.framework.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.ywx.framework.common.enums.DataSourceType;
import com.ywx.framework.config.properties.DruidProperties;
import com.ywx.framework.datasource.DynamicDataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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;
import java.util.HashMap;
import java.util.Map;
/**
* @author ywx
* @date 2019-06-25-10:16
*/
@Configuration
public class DruidConfig
@Bean
@ConfigurationProperties("spring.datasource.druid.datasource1")
public DataSource tmsDataSource(DruidProperties druidProperties)
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
@Bean
@ConfigurationProperties("spring.datasource.druid.datasource2")
//@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public DataSource pacsDataSource(DruidProperties druidProperties)
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
@Bean
@ConfigurationProperties("spring.datasource.druid.datasource3")
public DataSource ecgDataSource(DruidProperties druidProperties)
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
@Bean(name = "dynamicDataSource")
@Primary
public DynamicDataSource dataSource(DataSource tmsDataSource, DataSource pacsDataSource, DataSource ecgDataSource)
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceType.FIRST.name(), tmsDataSource);
targetDataSources.put(DataSourceType.SECOND.name(), pacsDataSource);
targetDataSources.put(DataSourceType.THIRD.name(), ecgDataSource);
return new DynamicDataSource(tmsDataSource, targetDataSources);
以上,已经完成了MySQL和Oracle数据源的配置了,数据源可以正常连接,但是查询数据后如果需要通过PageHelper实现分页的话,还需要配置PageHelper支持不同类型数据库分页sql的切换。
二、PageHelper配置自动支持不同类型数据库分页的切换
如果使用单库连接,可以使用以下配置:
# PageHelper分页插件
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
可以参考PageHelper官网文档
(1) helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012,否则会使用 SqlServer2005 的方式进行分页。
你也可以实现 AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。
(2) offsetAsPageNum:默认值为 false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为 true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使用,可以用页码和页面大小两个参数进行分页。
(3) rowBoundsWithCount:默认值为false,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为true时,使用 RowBounds 分页会进行 count 查询。
(4) pageSizeZero:默认值为 false,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。
(5) reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
(6) params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。
(7) supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。
(8) autoRuntimeDialect:默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择sqlserver2012,只能使用sqlserver)
如果使用多数据源,需要修改pagehelper配置项,配置如下:
# PageHelper分页插件
pagehelper:
# helperDialect: mysql
reasonable: false
supportMethodsArguments: true
params: count=countSql
# 默认false,当为true时,自动检验适合的数据库
auto-dialect: true
# 这个一定要加上,不然mysql和oracle分页两个只能用一个,另一个会报错,加上后,两中数据库分页都可以用了
auto-runtime-dialect: true
以上,已经完成支持不同类型数据库多数据源的连接已经分页实现了。
以上是关于SpringBoot+druid同时连接不同类型数据库及PageHelper支持多类型库查询分页功能的主要内容,如果未能解决你的问题,请参考以下文章