1. 首页 > PostgreSQL教程 > 正文

PostgreSQL教程FG142-PG与Java对接:JDBC驱动配置与实操

本文档风哥主要介绍PostgreSQL与Java的对接方法,重点关注JDBC驱动的配置与使用。风哥教程参考PostgreSQL官方文档Client Interfaces部分的Java相关内容,适合开发人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。更多视频教程www.fgedu.net.cn

Part01-基础概念与理论知识

1.1 JDBC的概念

JDBC(Java Database Connectivity)是Java语言访问数据库的标准接口,它提供了一套用于执行SQL语句的API,使Java应用程序能够与各种数据库进行交互。

JDBC的特点:

  • 标准化:提供统一的数据库访问接口
  • 跨平台:可以在任何支持Java的平台上使用
  • 灵活性:支持多种数据库
  • 安全性:提供参数化查询,防止SQL注入

1.2 JDBC的架构

JDBC架构包括:

  • JDBC API:提供应用程序与数据库交互的接口
  • JDBC驱动管理器:负责加载和管理驱动
  • JDBC驱动:实现特定数据库的连接和操作

1.3 PostgreSQL JDBC驱动

PostgreSQL JDBC驱动是专门为PostgreSQL数据库开发的JDBC驱动,它实现了JDBC API,允许Java应用程序连接到PostgreSQL数据库。

风哥提示:PostgreSQL JDBC驱动是官方维护的,支持PostgreSQL的所有主要特性,性能优异。学习交流加群风哥微信: itpux-com

Part02-生产环境规划与建议

2.1 JDBC驱动安装

JDBC驱动的安装方法:

# 1. 使用Maven添加依赖

org.postgresql
postgresql
42.7.3

# 2. 使用Gradle添加依赖
implementation ‘org.postgresql:postgresql:42.7.3’

# 3. 手动下载JAR包
# 从官网下载:https://jdbc.postgresql.org/download.html
# 将下载的JAR包添加到项目的classpath中

2.2 连接配置

连接配置参数:

  • url:数据库连接URL,格式为jdbc:postgresql://host:port/database
  • user:数据库用户名
  • password:数据库密码
  • 其他参数:如连接超时、SSL设置等

2.3 性能调优

性能调优考虑因素:

  • 连接池:使用连接池管理连接
  • 批量操作:使用批处理减少网络往返
  • 预编译语句:使用PreparedStatement提高性能
  • fetch size:设置合适的fetch size
风哥教程针对风哥教程针对生产环境建议:在生产环境中,建议使用连接池管理数据库连接,以提高性能和可靠性。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 基础操作

3.1.1 连接数据库

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class BasicConnection {
public static void main(String[] args) {
Connection conn = null;
try {
// 加载驱动
Class.forName(“org.postgresql.Driver”);

// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);
System.out.println(“连接成功”);

} catch (ClassNotFoundException e) {
System.out.println(“驱动加载失败: ” + e.getMessage());
} catch (SQLException e) {
System.out.println(“连接失败: ” + e.getMessage());
} finally {
if (conn != null) {
try {
conn.close();
System.out.println(“连接已关闭”);
} catch (SQLException e) {
System.out.println(“关闭连接失败: ” + e.getMessage());
}
}
}
}
}

// 输出示例
连接成功
连接已关闭

3.1.2 执行SQL查询

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class BasicQuery {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 创建Statement
stmt = conn.createStatement();

// 执行查询
String sql = “SELECT * FROM fgedu_users”;
rs = stmt.executeQuery(sql);

// 处理结果
while (rs.next()) {
int id = rs.getInt(“id”);
String name = rs.getString(“name”);
String email = rs.getString(“email”);
System.out.println(“ID: ” + id + “, Name: ” + name + “, Email: ” + email);
}

} catch (SQLException e) {
System.out.println(“查询失败: ” + e.getMessage());
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
ID: 1, Name: 张三, Email: zhangsan@fgedu.net.cn
ID: 2, Name: 李四, Email: lisi@fgedu.net.cn
ID: 3, Name: 王五, Email: wangwu@fgedu.net.cn

3.1.3 使用PreparedStatement

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class PreparedStatementExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 创建PreparedStatement
String sql = “SELECT * FROM fgedu_users WHERE id = ?”;
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 1); // 设置参数

// 执行查询
rs = pstmt.executeQuery();

// 处理结果
if (rs.next()) {
int id = rs.getInt(“id”);
String name = rs.getString(“name”);
String email = rs.getString(“email”);
System.out.println(“ID: ” + id + “, Name: ” + name + “, Email: ” + email);
}

} catch (SQLException e) {
System.out.println(“查询失败: ” + e.getMessage());
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
ID: 1, Name: 张三, Email: zhangsan@fgedu.net.cn

3.2 高级操作

3.2.1 执行更新操作

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UpdateExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 创建PreparedStatement
String sql = “UPDATE fgedu_users SET name = ? WHERE id = ?”;
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, “张三更新”);
pstmt.setInt(2, 1);

// 执行更新
int rows = pstmt.executeUpdate();
System.out.println(“更新了 ” + rows + ” 行”);

} catch (SQLException e) {
System.out.println(“更新失败: ” + e.getMessage());
} finally {
// 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
更新了 1 行

3.2.2 执行插入操作

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class InsertExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 创建PreparedStatement
String sql = “INSERT INTO fgedu_users (name, email) VALUES (?, ?)”;
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, “赵六”);
pstmt.setString(2, “zhaoliu@fgedu.net.cn”);

// 执行插入
int rows = pstmt.executeUpdate();
System.out.println(“插入了 ” + rows + ” 行”);

} catch (SQLException e) {
System.out.println(“插入失败: ” + e.getMessage());
} finally {
// 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
插入了 1 行

3.3 事务管理

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TransactionExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 开始事务
conn.setAutoCommit(false);

// 执行第一个更新
String sql1 = “UPDATE fgedu_users SET name = ? WHERE id = ?”;
pstmt1 = conn.prepareStatement(sql1);
pstmt1.setString(1, “张三事务更新”);
pstmt1.setInt(2, 1);
pstmt1.executeUpdate();

// 执行第二个更新
String sql2 = “UPDATE fgedu_users SET name = ? WHERE id = ?”;
pstmt2 = conn.prepareStatement(sql2);
pstmt2.setString(1, “李四事务更新”);
pstmt2.setInt(2, 2);
pstmt2.executeUpdate();

// 提交事务
conn.commit();
System.out.println(“事务提交成功”);

} catch (SQLException e) {
// 回滚事务
if (conn != null) {
try {
conn.rollback();
System.out.println(“事务回滚”);
} catch (SQLException ex) {
System.out.println(“回滚失败: ” + ex.getMessage());
}
}
System.out.println(“事务执行失败: ” + e.getMessage());
} finally {
// 恢复自动提交
if (conn != null) {
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
System.out.println(“设置自动提交失败: ” + e.getMessage());
}
}

// 关闭资源
try {
if (pstmt1 != null) pstmt1.close();
if (pstmt2 != null) pstmt2.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
事务提交成功

3.4 批量处理

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BatchExample {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;

try {
// 连接数据库
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

conn = DriverManager.getConnection(url, user, password);

// 禁用自动提交
conn.setAutoCommit(false);

// 创建PreparedStatement
String sql = “INSERT INTO fgedu_users (name, email) VALUES (?, ?)”;
pstmt = conn.prepareStatement(sql);

// 添加批量操作
pstmt.setString(1, “孙七”);
pstmt.setString(2, “sunqi@fgedu.net.cn”);
pstmt.addBatch();

pstmt.setString(1, “周八”);
pstmt.setString(2, “zhouba@fgedu.net.cn”);
pstmt.addBatch();

pstmt.setString(1, “吴九”);
pstmt.setString(2, “wuju@fgedu.net.cn”);
pstmt.addBatch();

// 执行批量操作
int[] results = pstmt.executeBatch();

// 提交事务
conn.commit();

System.out.println(“批量插入成功,影响了 ” + results.length + ” 行”);

} catch (SQLException e) {
// 回滚事务
if (conn != null) {
try {
conn.rollback();
System.out.println(“事务回滚”);
} catch (SQLException ex) {
System.out.println(“回滚失败: ” + ex.getMessage());
}
}
System.out.println(“批量插入失败: ” + e.getMessage());
} finally {
// 恢复自动提交
if (conn != null) {
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
System.out.println(“设置自动提交失败: ” + e.getMessage());
}
}

// 关闭资源
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
System.out.println(“关闭资源失败: ” + e.getMessage());
}
}
}
}

// 输出示例
批量插入成功,影响了 3 行

风哥提示:批量处理可以显著提高数据操作的性能,特别是对于大量数据的插入和更新操作。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 基础示例

4.1.1 用户管理系统

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserManager {
private Connection conn;

public UserManager(String url, String user, String password) throws SQLException {
this.conn = DriverManager.getConnection(url, user, password);
}

public void addUser(String name, String email) throws SQLException {
String sql = “INSERT INTO fgedu_users (name, email) VALUES (?, ?)”;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setString(2, email);
int rows = pstmt.executeUpdate();
System.out.println(“添加用户成功,影响了 ” + rows + ” 行”);
}
}

public void updateUser(int id, String name, String email) throws SQLException {
String sql = “UPDATE fgedu_users SET name = ?, email = ? WHERE id = ?”;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setString(2, email);
pstmt.setInt(3, id);
int rows = pstmt.executeUpdate();
System.out.println(“更新用户成功,影响了 ” + rows + ” 行”);
}
}

public void deleteUser(int id) throws SQLException {
String sql = “DELETE FROM fgedu_users WHERE id = ?”;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
int rows = pstmt.executeUpdate();
System.out.println(“删除用户成功,影响了 ” + rows + ” 行”);
}
}

public void getUser(int id) throws SQLException {
String sql = “SELECT * FROM fgedu_users WHERE id = ?”;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
System.out.println(“ID: ” + rs.getInt(“id”));
System.out.println(“Name: ” + rs.getString(“name”));
System.out.println(“Email: ” + rs.getString(“email”));
} else {
System.out.println(“用户不存在”);
}
}
}
}

public void getAllUsers() throws SQLException {
String sql = “SELECT * FROM fgedu_users”;
try (PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
System.out.println(“ID: ” + rs.getInt(“id”) + “, Name: ” + rs.getString(“name”) + “, Email: ” + rs.getString(“email”));
}
}
}

public void close() throws SQLException {
if (conn != null) {
conn.close();
}
}

public static void main(String[] args) {
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

try (UserManager manager = new UserManager(url, user, password)) {
// 添加用户
manager.addUser(“钱十”, “qianshi@fgedu.net.cn”);

// 获取用户
manager.getUser(4);

// 更新用户
manager.updateUser(4, “钱十更新”, “qianshi_updated@fgedu.net.cn”);

// 获取所有用户
manager.getAllUsers();

} catch (SQLException e) {
System.out.println(“操作失败: ” + e.getMessage());
}
}
}

// 输出示例
添加用户成功,影响了 1 行
ID: 4, Name: 钱十, Email: qianshi@fgedu.net.cn
更新用户成功,影响了 1 行
ID: 1, Name: 张三事务更新, Email: zhangsan@fgedu.net.cn
ID: 2, Name: 李四事务更新, Email: lisi@fgedu.net.cn
ID: 3, Name: 王五, Email: wangwu@fgedu.net.cn
ID: 4, Name: 钱十更新, Email: qianshi_updated@fgedu.net.cn

4.2 连接池示例

4.2.1 使用HikariCP连接池

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ConnectionPoolExample {
private static HikariDataSource dataSource;

static {
// 配置连接池
HikariConfig config = new HikariConfig();
config.setJdbcUrl(“jdbc:postgresql://fgedu.localhost:5432/fgedudb”);
config.setUsername(“fgedu”);
config.setPassword(“fgedu123”);
config.setMaximumPoolSize(10);
config.setMinimumIdle(5);
config.setIdleTimeout(30000);
config.setMaxLifetime(1800000);

dataSource = new HikariDataSource(config);
}

public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}

public static void main(String[] args) {
try (Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement(“SELECT * FROM fgedu_users”);
ResultSet rs = pstmt.executeQuery()) {

while (rs.next()) {
System.out.println(“ID: ” + rs.getInt(“id”) + “, Name: ” + rs.getString(“name”) + “, Email: ” + rs.getString(“email”));
}

} catch (SQLException e) {
System.out.println(“操作失败: ” + e.getMessage());
}
}
}

// 输出示例
ID: 1, Name: 张三事务更新, Email: zhangsan@fgedu.net.cn
ID: 2, Name: 李四事务更新, Email: lisi@fgedu.net.cn
ID: 3, Name: 王五, Email: wangwu@fgedu.net.cn
ID: 4, Name: 钱十更新, Email: qianshi_updated@fgedu.net.cn

4.3 批量操作示例

4.3.1 批量导入数据

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class BatchImportExample {
public static void main(String[] args) {
String url = “jdbc:postgresql://fgedu.localhost:5432/fgedudb”;
String user = “fgedu”;
String password = “fgedu123”;

Connection conn = null;
PreparedStatement pstmt = null;

try {
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);

String sql = “INSERT INTO fgedu_users (name, email) VALUES (?, ?)”;
pstmt = conn.prepareStatement(sql);

// 批量插入1000条数据
for (int i = 1; i <= 1000; i++) { pstmt.setString(1, "用户" + i); pstmt.setString(2, "user" + i + "@fgedu.net.cn"); pstmt.addBatch(); // 每100条执行一次 if (i % 100 == 0) { pstmt.executeBatch(); pstmt.clearBatch(); System.out.println("已插入 " + i + " 条数据"); } } // 执行剩余的批次 pstmt.executeBatch(); conn.commit(); System.out.println("批量导入完成,共插入 1000 条数据"); } catch (SQLException e) { if (conn != null) { try { conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { try { if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } // 输出示例 已插入 100 条数据 已插入 200 条数据 已插入 300 条数据 已插入 400 条数据 已插入 500 条数据 已插入 600 条数据 已插入 700 条数据 已插入 800 条数据 已插入 900 条数据 已插入 1000 条数据 批量导入完成,共插入 1000 条数据

风哥教程针对风哥教程针对生产环境建议:在生产环境中,使用连接池和批量操作可以显著提高性能,特别是对于高并发场景。from PostgreSQL视频:www.itpux.com

Part05-风哥经验总结与分享

5.1 JDBC最佳实践

JDBC最佳实践:

  • 使用连接池:在生产环境中,使用连接池管理数据库连接
  • 使用PreparedStatement:防止SQL注入,提高性能
  • 合理管理事务:根据业务需求选择合适的事务隔离级别
  • 批量操作:对于大量数据操作,使用批量插入和更新
  • 资源管理:使用try-with-resources语句确保资源正确释放
  • 错误处理:实现完善的错误处理机制

5.2 常见问题与解决方案

常见问题及解决方案:

# 问题1:连接泄漏
# 解决方法:使用try-with-resources语句或在finally块中关闭连接

# 问题2:SQL注入
# 解决方法:使用PreparedStatement,避免直接拼接SQL语句

# 问题3:性能问题
# 解决方法:使用连接池、批量操作、预编译语句等

# 问题4:内存泄漏
# 解决方法:确保所有资源(Connection、Statement、ResultSet)都被正确关闭

# 问题5:事务管理问题
# 解决方法:合理使用事务,确保事务的原子性、一致性、隔离性和持久性

5.3 性能优化技巧

性能优化技巧:

  • 使用连接池:减少连接建立和关闭的开销
  • 批量操作:减少网络往返次数
  • 预编译语句:提高查询执行效率
  • 合理设置fetch size:对于大型结果集,设置合适的fetch size
  • 使用批处理:对于大量数据操作,使用addBatch和executeBatch
  • 优化SQL语句:编写高效的SQL语句,使用索引
持续改进:定期监控和优化数据库操作,根据实际情况调整优化策略,以获得最佳性能。

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息