java 连接 oracle 数据库需要引入 jdbc 驱动包,使用 class.forname 加载驱动类,并通过 drivermanager.getconnection 方法传入 url、用户名和密码建立连接。推荐使用 oracle 官方提供的 ojdbc8.jar 或更高版本驱动,确保与 jdk 版本兼容。

JDBC URL 的格式和关键参数有哪些
JDBC URL 必须遵循 jdbc:oracle:thin:@host:port:sid 或 jdbc:oracle:thin:@//host:port/service_name 的格式。其中 host 是数据库服务器地址,port 默认是 1521,sid 是实例名,而 service_name 是服务名。在 Oracle 12c 及以上版本中,推荐使用服务名而非 SID,因为多租户架构下 CDB/PDB 结构更常见。如果连接失败,检查防火墙是否放行端口,以及监听器是否注册了正确的服务。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class OracleJdbcExample {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@//localhost:1521/orclpdb1";
String user = "scott";
String password = "tiger";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
if (conn != null) {
System.out.println("Connected to Oracle database successfully.");
} else {
System.out.println("Failed to connect.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
上述代码中,URL 使用了 // 表示服务名模式。如果使用的是旧版 SID 模式,则去掉 // 并替换 orclpdb1 为 SID 名称。驱动类 oracle.jdbc.OracleDriver 在 JDBC 4.0+ 中可自动加载,无需显式调用 Class.forName,但为了兼容性,部分项目仍保留该调用。连接对象 conn 实现了 AutoCloseable,因此可以使用 try-with-resources 语句自动关闭资源,避免内存泄漏。
立即学习“Java免费学习笔记(深入)”;
如何处理连接超时和异常
连接 Oracle 时常见的异常包括 ORA-12514(监听器未识别服务)、ORA-12505(SID 错误)和 CommunicationsException(网络不通)。处理这些异常时,应捕获 SQLException 并检查 getErrorCode() 以区分具体原因。对于超时问题,可以在 URL 中添加 connect_timeout 和 receive_timeout 参数,或者在 Properties 中设置 oracle.net.CONNECT_TIMEOUT。此外,启用连接池如 HikariCP 可以自动重试和失效检测,提高稳定性。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class OracleJdbcWithTimeout {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@//localhost:1521/orclpdb1";
Properties props = new Properties();
props.setProperty("user", "scott");
props.setProperty("password", "tiger");
props.setProperty("oracle.net.CONNECT_TIMEOUT", "5000"); // 5秒超时
try (Connection conn = DriverManager.getConnection(url, props)) {
System.out.println("Connected with timeout settings.");
} catch (SQLException e) {
System.err.println("Error code: " + e.getErrorCode());
System.err.println("Message: " + e.getMessage());
}
}
}
在上面的代码中,通过 Properties 对象设置了连接超时时间为 5000 毫秒。当数据库不可达或响应缓慢时,驱动程序会在指定时间内抛出 SQLException,而不是无限期等待。开发者可以根据实际网络环境调整该值。同时,建议在生产环境中结合连接池使用,以实现更健壮的连接管理。
使用 PreparedStatement 防止 SQL 注入的具体做法是什么
在使用 JDBC 执行查询时,必须使用 PreparedStatement 而非 Statement 来拼接用户输入,以防止 SQL 注入攻击。PreparedStatement 通过预编译 SQL 模板并将参数绑定到占位符 ? 上,确保用户输入被当作数据而非 SQL 代码执行。例如,查询用户信息时,将用户名作为参数传入,而不是直接拼接到 SQL 字符串中。这样可以彻底隔离代码与数据,提升安全性。
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SafeQueryExample {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@//localhost:1521/orclpdb1";
String user = "scott";
String password = "tiger";
String inputUsername = "admin' OR '1'='1"; // 恶意输入
String sql = "SELECT * FROM users WHERE username = ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, inputUsername);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
System.out.println("Found user: " + rs.getString("username"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
在上述代码中,SQL 语句包含一个占位符 ?,然后通过 pstmt.setString(1, inputUsername) 将用户输入绑定到第一个参数。即使输入包含 SQL 关键字,它也会被当作普通字符串处理,不会改变 SQL 逻辑。这是防御 SQL 注入的标准做法,适用于所有涉及用户输入的数据库操作场景。


















