参考文章:springboot使用druid连接池连接Oracle数据库的基本配置
springboot---整合druid连接池---连接oracle数据库---整合mybatis---整合thymeleaf---日志配置
引入oracle ojdbc驱动
由于Oracle是收费的,Maven不提供Oracle JDBC driver,在Maven项目中应用Oracle JDBC driver,必须手动添加到本地仓库。
1、查看Oracle版本
select * from v$instance
2、Oracle 对应Jdbc驱动版本
pom.xml配置
虽然通过版本确定为ojdbc6版本,但这里需要引入用ojdbc8版本才可以。
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>18.3</version>
</dependency>
具体pom如下:
<?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.11.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<project-name>druid-jdbc-orcl</project-name>
</properties>
<groupId>org.find</groupId>
<artifactId>${project-name}</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project-name}</name>
<description>${project-name}</description>
<dependencies>
<!-- ============= 数据库连接jdbc依赖 start ============= -->
<!-- 依赖 spring-jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc8</artifactId>
<version>18.3</version>
</dependency>
<!--阿里druid数据库链接依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
<!-- ============= 数据库连接jdbc依赖 end ============= -->
<!-- 上边引入 parent,因此 下边无需指定版本 -->
<!-- 包含 mvc,aop 等jar资源 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.15</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 解决资源文件的编码问题 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- maven打source包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<!--<phase>verify</phase>-->
<goals>
<!--jar, jar-no-fork-->
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- spring Boot在编译的时候,是有默认JDK版本的,这里自定义指定JDK版本 -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>org.fiend.SpringbootApplication</mainClass>
<useUniqueVersions>false</useUniqueVersions>
</manifest>
<!--<manifestEntries>-->
<!-- <Class-Path>./</Class-Path>-->
<!--</manifestEntries>-->
</archive>
<excludes>
<!--<exclude>*.properties</exclude>-->
<!--<exclude>*.yml</exclude>-->
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
application.yml文件配置:
# postgresql 环境配置
server:
port: 18015
max-http-header-size: 8192
#配置日志
logging:
level:
root: info
# 不同目录下的日志可配置不同级别 info, error
com.euler: debug
org.springfromework.web: info
spring:
application:
name: druid-jdbc-postgresql
mvc.async.request-timeout: 20000
http:
encoding:
charset: UTF-8
force: true
enabled: true
datasource:
url: jdbc:oracle:thin:@192.168.10.154:1521:orcl
username: test
password: 123
#driverClassName: org.postgresql.Driver
#platform: postgres
type: com.alibaba.druid.pool.DruidDataSource
#type: org.apache.commons.dbcp2.BasicDataSource
initialization-mode: always
# ============================== druid ============================== #
druid:
#最大活跃数
max-active: 20
#初始化数量
initial-size: 1
#最大连接等待超时时间
max-wait: 60000
min-idle: 1
#通过connectionProperties属性来打开mergeSql功能;慢SQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
#useGlobalDataSourceStat: true
# JDBC 配置(驱动类自动从url的mysql识别,数据源类型自动识别)
# spring.datasource.url: 或者:
# spring.datasource.druid.url: jdbc:mysql://192.168.1.1:3306/test?useUnicode=true&characterEncoding=UTF8
# spring.datasource.username: 或者
# spring.datasource.druid.username: root
# spring.datasource.password: 或者:
# spring.datasource.druid.password: root
# spring.datasource.driver-class-name: 或者:
# spring.datasource.druid.driver-class-name: com.mysql.jdbc.Driver
# 连接池配置(通常来说,只需要修改initialSize、minIdle、maxActive
# 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。
# 分库分表较多的数据库,建议配置为false。removeabandoned不建议在生产环境中打开如果用SQL Server,建议追加配置)
#打开PSCache,并且指定每个连接PSCache的大小
poolPreparedStatements: true
max-pool-prepared-statement-per-connection-size: 20
# max-open-prepared-statements: 和上面的等价
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
# max-evictable-idle-time-millis
# SELECT 'x'
validation-query: select 1 from dual
# validation-query-timeout:
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
filters: stat, wall, log4j
# Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置
# aop-patterns: # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
JDBC配置文件:
JdbcDao:
package org.fiend.jdbc;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
public interface JdbcDao {
public int insertAndReturnKey(String sql, Object[] paramVarArgs);
/**
* 通过Statement方式插入,
* 通过Statement可以指定参数类型,这种插入方式更加安全,
* 注意设置参数时,起始值为1,而不是通常说的0
* Statement方式插入, 方式一
*/
public boolean insertByStatement(String sql, Object[] paramVarArgs);
/**
* Statement方式插入, 方式二
*/
public boolean insertByStatement2(String sql, Object[] paramVarArgs);
/* =============================== query list =============================== */
public <T extends Serializable> List<T> queryBasic(String sql, Object[] paramVarArgs, Class<T> paramClass);
public <T> List<T> queryForSimpleList(String sql, Object[] paramVarArgs, Class<T> elementType);
public <T> List<T> queryForList(String sql, Object[] paramVarArgs, Class<T> elementType);
public List<Map<String, Object>> queryForList(String sql, Object[] paramVarArgs);
/**
* for sql map
* 元素需要遍历,再查询或执行复杂逻辑
*/
public <T> List<T> queryForList(String sql, RowMapper<T> rowMapper);
// public int queryForInt(String sql, Object[] paramVarArgs);
// public <T> Pagination queryForPagination(String sql, Pagination paramPagination, Object[] paramVarArgs, Class<T> paramClass);
public <T> List<T> query(String sql, Object[] paramVarArgs, Class<?> returnClass);
/**
* for sql in
*/
public <T> List<T> queryForIn(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper);
/* =============================== query object =============================== */
public <T> T queryForSimpleObject(String sql, Object[] paramVarArgs, Class<T> paramClass);
public Map<String, Object> queryForMap(String sql, Object[] paramVarArgs);
/**
* @param sql sql
* @param args args
* @param argTypes Types.INTEGER ...
* @return map
*/
public Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes);
public <T> T queryForObject(String sql, Object[] paramVarArgs, Class<T> paramClass);
/* =============================== batch update =============================== */
public int update(String sql, Object[] paramVarArgs);
public int update(String sql, PreparedStatementSetter pss);
public int[] batchUpdate(String sql, List<Object[]> paramList);
/**
* 通过Statement方式插入,
* 通过Statement可以指定参数类型,这种插入方式更加安全,
* 注意设置参数时,起始值为1,而不是通常说的0
*/
public int[] batchInsertByStatement(String sql, List<Object[]> paramList);
// 批量插入并返回主键id, 具体见博客:
// public int batchInsertAndReturnId(String sql, List<Object[]> paramList);
public void execute(String sql);
}
JdbcDaoImpl:
package org.fiend.jdbc.impl;
import org.fiend.jdbc.JdbcDao;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import javax.validation.constraints.Null;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static java.sql.Types.NULL;
/**
* @author Administrator
*/
// @Repository
public class JdbcDaoImpl implements JdbcDao {
private JdbcTemplate jdbcTemplate;
public JdbcDaoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* 插入并返回主键id
*/
@Override
public int insertAndReturnKey(String sql, Object[] paramVarArgs) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
// 在获取Statement时,需要制定主键,否则会报错
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
setParamVarArgs(ps, paramVarArgs);
return ps;
}
}, keyHolder);
return keyHolder.getKey().intValue();
}
/**
* 通过Statement方式插入,
* 通过Statement可以指定参数类型,这种插入方式更加安全,
* 注意设置参数时,起始值为1,而不是通常说的0
* Statement方式插入, 方式一
*/
@Override
public boolean insertByStatement(String sql, Object[] paramVarArgs) {
return jdbcTemplate.update(sql, new PreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement) throws SQLException {
setParamVarArgs(preparedStatement, paramVarArgs);
}
}) > 0;
}
/**
* Statement方式插入, 方式二
*/
@Override
public boolean insertByStatement2(String sql, Object[] paramVarArgs) {
return jdbcTemplate.update(connection -> {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
setParamVarArgs(preparedStatement, paramVarArgs);
return preparedStatement;
}) > 0;
}
private void setParamVarArgs(PreparedStatement ps, Object[] paramVarArgs) throws SQLException {
for (int i = 0; i < paramVarArgs.length; i++) {
if (paramVarArgs[i] instanceof String) {
ps.setString(i + 1, paramVarArgs[i].toString());
continue;
}
if (paramVarArgs[i] instanceof Integer) {
ps.setInt(i + 1, Integer.parseInt(String.valueOf(paramVarArgs[i])));
continue;
}
if (paramVarArgs[i] instanceof Date) {
ps.setDate(i + 1, new java.sql.Date(((Date) paramVarArgs[i]).getTime()));
continue;
}
if (paramVarArgs[i] instanceof Long) {
ps.setLong(i + 1, Long.parseLong(String.valueOf(paramVarArgs[i])));
continue;
}
if (paramVarArgs[i] instanceof Double) {
ps.setDouble(i + 1, Double.parseDouble(String.valueOf(paramVarArgs[i])));
continue;
}
if (paramVarArgs[i] instanceof Null) {
ps.setNull(i + 1, NULL);
continue;
}
if (paramVarArgs[i] instanceof BigDecimal) {
ps.setBigDecimal(i + 1, BigDecimal.valueOf(Long.parseLong(String.valueOf(paramVarArgs[i]))));
}
}
}
/* =============================== query list =============================== */
@Override
public <T extends Serializable> List<T> queryBasic(String sql,
Object[] paramVarArgs, Class<T> paramClass) {
return this.jdbcTemplate.queryForList(sql, paramClass, paramVarArgs);
}
@Override
public <T> List<T> queryForSimpleList(String sql, Object[] paramVarArgs, Class<T> elementType) {
try {
return this.jdbcTemplate.queryForList(sql, elementType, paramVarArgs);
} catch (Exception ignored) {
}
return null;
}
@Override
public <T> List<T> queryForList(String sql, Object[] paramVarArgs, Class<T> elementType) {
try {
RowMapper<T> rm = BeanPropertyRowMapper.newInstance(elementType);
return this.jdbcTemplate.query(sql, paramVarArgs, rm);
} catch (Exception ignored) {
}
return null;
}
@Override
public List<Map<String, Object>> queryForList(String sql,
Object[] paramVarArgs) {
return this.jdbcTemplate.queryForList(sql, paramVarArgs);
}
@Override
public <T> List<T> queryForList(String sql, RowMapper<T> rowMapper) {
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(this.jdbcTemplate);
return namedJdbcTemplate.query(sql, rowMapper);
}
// @Override
// public int queryForInt(String sql, Object[] paramVarArgs) {
// return this.jdbcTemplate.queryForInt(sql, paramVarArgs);
// }
@Override
public <T> List<T> query(String sql, Object[] paramVarArgs,
Class<?> returnClass) {
return (List<T>) this.jdbcTemplate.query(sql, paramVarArgs, BeanPropertyRowMapper.newInstance(returnClass));
}
@Override
public <T> List<T> queryForIn(String sql, SqlParameterSource paramSource, RowMapper<T> rowMapper) {
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(this.jdbcTemplate);
return namedJdbcTemplate.query(sql, paramSource, rowMapper);
}
/* =============================== query object =============================== */
@Override
public <T> T queryForSimpleObject(String sql, Object[] paramVarArgs, Class<T> paramClass) {
try {
return this.jdbcTemplate.queryForObject(sql, paramVarArgs, paramClass);
} catch (Exception ignored) {
}
return null;
}
@Override
public Map<String, Object> queryForMap(String sql, Object[] paramVarArgs) {
return this.jdbcTemplate.queryForMap(sql, paramVarArgs);
}
@Override
public Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes) {
return this.jdbcTemplate.queryForMap(sql, args, argTypes);
}
@Override
public <T> T queryForObject(String sql, Object[] paramVarArgs,
Class<T> paramClass) {
try {
RowMapper<T> rm = BeanPropertyRowMapper.newInstance(paramClass);
List<T> list = this.jdbcTemplate.query(sql, paramVarArgs, rm);
if (list.size() > 0) {
return list.get(0);
}
} catch (Exception ignored) {
}
return null;
}
/* =============================== batch update =============================== */
@Override
public int update(String sql, Object[] paramVarArgs) {
return this.jdbcTemplate.update(sql, paramVarArgs);
}
@Override
public int update(String sql, PreparedStatementSetter pss) {
return this.jdbcTemplate.update(sql, pss);
}
@Override
public int[] batchUpdate(String sql, List<Object[]> paramList) {
return this.jdbcTemplate.batchUpdate(sql, paramList);
}
@Override
public int[] batchInsertByStatement(String sql, List<Object[]> paramList) {
return jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement preparedStatement, int i) throws SQLException {
setParamVarArgs(preparedStatement, paramList.get(i));
}
@Override
public int getBatchSize() {
return 2;
}
});
}
@Override
public void execute(String sql) {
this.jdbcTemplate.execute(sql);
}
}
OrclDataSourceConfig:
package org.fiend.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.fiend.jdbc.JdbcDao;
import org.fiend.jdbc.impl.JdbcDaoImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
/**
* postgresql data source config
* @author test
*/
@Configuration
public class OrclDataSourceConfig {
@Bean(name = "jdbcDao")
@Qualifier("jdbcDao")
public JdbcDao jdbcDao(@Qualifier("jdbcTemplate") JdbcTemplate jdbcTemplate) {
return new JdbcDaoImpl(jdbcTemplate);
}
@Bean(name = "jdbcTemplate")
@Qualifier("jdbcTemplate")
public JdbcTemplate jdbcTemplate(@Qualifier("dataSource") DruidDataSource dds) {
return new JdbcTemplate(dds);
}
@Bean(name = "dataSource")
@Qualifier("dataSource")
@ConfigurationProperties(prefix="spring.datasource")
public DruidDataSource DataSource() {
return DruidDataSourceBuilder.create().build();
}
}
Controller文件
package org.fiend.controller;
import com.alibaba.fastjson.JSONObject;
import org.fiend.jdbc.JdbcDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
/**
* @author Administrator
*/
@RestController
@RequestMapping("test")
public class TestController {
Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
JdbcDao jdbcDao;
@RequestMapping("orcl")
public JSONObject orclConnTest() {
JSONObject json = new JSONObject();
String sql = "select * from mdc_di_path where rownum<=1";
List<Map<String, Object>> dataList = jdbcDao.queryForList(sql, new Object[]{});
json.put("data", dataList);
return json;
}
}