SpringBoot 连接Oracle 12c 以上版本PDB的解决思路

1. 最近公司产品改用springboot开发, 要支持企业级大型数据库Oracle ,并且版本要求比较高,需要使用Oracle12c以上.

又因为Oracle 12c 以上有了一个PDB的可插拔数据库的概念. 之前公司同事要求使用非PDB模式进行建账套使用, 所以最近的很多机器都是简单的non-PDB模式的. 

这几天有同事自行搭建数据库, 使用了PDB模式,结果发现springboot注册数据库时报错,经过自己的搜索和实验, 问题和思路主要如下:

2. 问题现象. 注册完数据库之后, 

  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:oracle:thin:@10.24.14.56:1521:pdbora12c^M
    driver-class-name: oracle.jdbc.driver.OracleDriver^M
    username: gscloud^M
    password: Test6530^M

启动会报错:

java.sql.SQLException: Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
 
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:854) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
    at oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:793) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:57) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:747) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:562) ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136) ~[HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369) ~[HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) ~[HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) [HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) [HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) [HikariCP-3.2.0.jar!/:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) [HikariCP-3.2.0.jar!/:na]
    at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:158) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
    at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:116) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
    at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:226) [spring-jdbc-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
    at com.sun.proxy.$Proxy696.prepareStatement(Unknown Source) [na:na]

解决思路:

替换连接字符串为:

修改点有两处:

1. @后面添加两个 正斜线   

2.端口号后面将之前的冒号修改为 正斜线. 

  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:oracle:thin:@//10.24.14.56:1521/pdbora12c^M
    driver-class-name: oracle.jdbc.driver.OracleDriver^M
    username: gscloud^M
    password: Test6530^M

3. 再次启动 

验证服务能够正常启动起来. 

这里面转帖一下别人对SID和SERVICE_NAME的简单说明.

3.1 java连接Oracle数据库的三种格式:

格式一:jdbc:oracle:thin:@//<host>:<port>/<service_name>
格式二:jdbc:oracle:thin:@<host>:<port>:<SID> 
格式三:jdbc:oracle:thin:@<TNSName>

3.2 service_name 和sid的区别: 

Service_name:该参数是由oracle8i引进的。在8i以前,使用SID来表示标识数据库的一个实例,但是在Oracle的并行环境中,一个数据库对应多个实例,这样就需要多个网络服务名,设置繁琐。为了方便并行环境中的设置,引进了Service_name参数,该参数对应一个数据库,而不是一个实例,而且该参数有许多其它的好处。该参数的缺省值为Db_name. Db_domain,即等于Global_name。一个数据库可以对应多个Service_name,以便实现更灵活的配置。该参数与SID没有直接关系,即不必Service name 必须与SID一样 
sid是数据库实例的名字,每个实例各不相同。 

 

 

 

posted @ 2020-02-09 12:37  济南小老虎  阅读(2871)  评论(0编辑  收藏  举报