参考文章: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

druid连接mysql配置 druid连接oracle数据库_spring

2、Oracle 对应Jdbc驱动版本

druid连接mysql配置 druid连接oracle数据库_maven_02

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;
	}
}