我需要设置一些特定的Oracle JDBC连接属性,以便加快批处理mysql_*
s(INSERT
)和质量defaultBatchValue
s(SELECT
)。
我得到了suggestions如何通过DBCP实现这一目标(感谢M. Deinum),但我想:
我正在考虑将来支持defaultRowPrefetch
或类似功能的功能请求,并且由于此尝试已经可以实现这一点。我这样做是通过在创建DataSource时传递相关信息并操纵DataSource的创建,如下所示:
spring.datasource.custom_connection_properties
在日志中我可以看到我正在创建正确的DataSource:
@Bean
public DataSource dataSource() {
DataSource ds = null;
try {
Field props = DataSourceBuilder.class.getDeclaredField("properties");
props.setAccessible(true);
DataSourceBuilder builder = DataSourceBuilder.create();
Map<String, String> properties = (Map<String, String>) props.get(builder);
properties.put("defaultRowPrefetch", "1000");
properties.put("defaultBatchValue", "1000");
ds = builder.url( "jdbc:oracle:thin:@xyz:1521:abc" ).username( "ihave" ).password( "wonttell" ).build();
properties = (Map<String, String>) props.get(builder);
log.debug("properties after: {}", properties);
} ... leaving out the catches ...
}
log.debug("We are using this datasource: {}", ds);
return ds;
}
执行器向我显示我的代码替换了数据源:
但是没有激活设置,我在分析应用程序时可以看到。 2016-01-18 14:40:32.924 DEBUG 31204 --- [ main] d.a.e.a.c.config.DatabaseConfiguration : We are using this datasource: org.apache.tomcat.jdbc.pool.DataSource@19f040ba{ConnectionPool[defaultAutoCommit=null; ...
2016-01-18 14:40:32.919 DEBUG 31204 --- [ main] d.a.e.a.c.config.DatabaseConfiguration : properties after: {password=wonttell, driverClassName=oracle.jdbc.OracleDriver, defaultRowPrefetch=1000, defaultBatchValue=1000, url=jdbc:oracle:thin:@xyz:1521:abc, username=ihave}
仍然在defaultRowPrefetch
,导致10
比SELECT
被激活时慢得多。
答案 0 :(得分:8)
设置池connectionProperties应该有效。这些将被传递给JDBC驱动程序。将其添加到application.properties:
spring.datasource.connectionProperties: defaultRowPrefetch=1000;defaultBatchValue=1000
编辑(一些背景信息):
另请注意,您可以配置任何DataSource实现 通过spring.datasource。*的具体属性:参考 您正在使用的连接池实现的文档 更多细节。
答案 1 :(得分:2)
补充@Cyril答案的一些其他信息。如果你想使用他的答案,而不是我的答案。
我有点困惑的是设置在创建数据库连接时最终使用的其他连接属性是多么容易。所以我做了一些研究。
reference中 spring.datasource.connectionProperties
未。因此,我创建了issue。
如果我使用了Spring Boot YML editor,我会看到支持哪些属性。以下是STS在您创建application.yml
并点击 Ctrl + Space 时的建议:
破折号因relaxed binding而无关紧要,但如果您从字面上理解其属性名称为spring.datasource.connection-properties
。
application.yml中的正确设置如下所示:
spring:
datasource:
connection-properties: defaultBatchValue=1000;defaultRowPrefetch=1000
...
这是值得尊重的,这可以通过我的perf4j质量SELECT
测量来证明。
在:
2016-01-19 08:58:32.604 INFO 15108 --- [主要] org.perf4j.TimingLogger:start [1453190311227] time [1377] tag [get elements]
后:
2016-01-19 08:09:18.214 INFO 9152 --- [主要] org.perf4j.TimingLogger:start [1453187358066] time [147] tag [get elements]
完成SQL语句所需的时间从1377ms降至147,这是性能的巨大提升。
答案 2 :(得分:1)
在挖掘Tomcat代码之后,我发现dataSource.getPoolProperties().getDbProperties()
是Properties
对象,它实际上将用于为池生成连接。
如果您使用@ m-deinum提到的BeanPostProcessor
方法,而是使用它来填充dbProperties
,那么您应该能够以一种使它们坚持的方式添加属性并传递给Oracle驱动程序。
import java.util.Properties;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolConfiguration;
@Component
public class OracleConfigurer implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof DataSource) {
DataSource dataSource = (DataSource)bean;
PoolConfiguration configuration = dataSource.getPoolProperties();
Properties properties = configuration.getDbProperties();
if (null == properties) properties = new Properties();
properties.put("defaultRowPrefetch", 1000);
properties.put("defaultBatchValue", 1000);
configuration.setDbProperties(properties);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
return bean;
}
}
答案 3 :(得分:1)
由于Spring Boot长期处于EOL状态,因此我切换到了带有新的默认连接池Hikari的Spring Boot 2.1。这里的解决方案更加简单,可以在application.properties或(如此处所示)application.yml中完成:
spring:
datasource:
hikari:
data-source-properties:
defaultRowPrefetch: 1000
(在实际配置中,会有其他一些配置项,但是由于它们与所问的问题无关,我只是在示例中将它们省略了)