当前位置: 首页 > news >正文

PostgreSQL15——Java访问PostgreSQL

Java访问PostgreSQL

  • 一、连接数据库
  • 二、创建和删除表
  • 三、插入数据
  • 四、查询数据
  • 五、修改数据
  • 六、删除数据
  • 七、处理事务
  • 八、调用存储过程

JDBC (Java Database Connectivity)是 Java 语言中用于访问数据库的应用程序接口(API)。JDBC 提供了操作关系数据库的标准方法,属于 Java Standard Edition 平台的一部分。以下是 Java应用程序通过JDBC 访问数据库的示意图:

在这里插入图片描述

其中各个模块的作用如下:

  • Java 应用程序由开发人员编码完成,用于实现业务处理的逻辑和流程;
  • JDBC API 提供了统一的接口和驱动管理,实现了应用程序和 JDBC 驱动的隔离。同一套应用代码只需要切换驱动程序就可以支持不同的数据库;
  • JDBC 驱动实现了JDBC API 中定义的接口,用于与不同的数据库进行交互;
  • 数据库提供数据的存储管理和访问控制。

一、连接数据库

Maven依赖:

<dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId><version>42.2.14</version>
</dependency>

在项目目录中创建一个数据库的连接配置文件 db.properties,内容如下:

url=jdbc:postgresql://192.168.56.104:3306/hrdb
user=tony
password=123456
package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;public class App {public static void main(String[] args) {String url = null;String user = null;String password = null;//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");} catch (SQLException e) {System.out.println(e.getMessage());}}
}

首先,通过一个FileInputStream 对象读取数据库的连接配置文件;然后使用try-with-resources方式建立数据库连接,打印信息。运行该程序的结果如下:

连接PostgreSQL数据库成功!

二、创建和删除表

  1. 通过JDBC 连接数据库并执行 DDL 语句的过程如下:
  2. 利用 DriverManager 类的 getConnection()方法获取一个 Connection 连接对象;
  3. 使用连接对象的 createStatement()方法创建一个Statement 语句对象;
  4. 利用语句对象的 execute()方法执行 SQ 语句;
    释放 Statement 以及 Connection 对象资源。
package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;public class PostgreSQLDDL {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "create table users (" +" id serial primary key," +" name character varying(10) not null unique," +" created_at timestamp not null" +")";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,创建查询语句,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");Statement ps = conn.createStatement();//执行SQL语句ps.execute(sql_str);System.out.println("成功创建users表!");} catch (SQLException e) {System.out.println(e.getMessage());}}
}

首先,通过一个 FileInputStream 对象读取数据库的连接配置文件;然后使用try-with-resources方式建立数据库连接,创建查询语句,并且执行语句创建 users 表。运行该程序的结果如下:

连接PostgreSQL数据库成功!
成功创建users表!

如果users 表已经存在,将会提示以下错误:

ERROR: relation "users" already exists

此时可以将 sql_str 的内容修改 drop table users 删除并重新创建 users 表。

三、插入数据

通过JDBC 连接数据库并执行插入操作的过程如下:

  1. 利用 DriverManager 类的 getConnection()方法获取一个 Connection 连接对象;
  2. 使用连接对象的 createStatement()方法创建一个 Statement 或者PreparedStatement 语句对
    象;
  3. 利用语句对象的 execute()或者executeBatch()方法执行 INSERT 语句;
  4. 释放 Statement 以及 Connection 对象资源。
package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class PostgreSQLInsert {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "insert into users(name, created_at)" +" values(?, ?)";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");PreparedStatement ps = conn.prepareStatement(sql_str);//设置输入参数ps.setString(1, "tony");ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));ps.addBatch();ps.setString(1, "david");ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));ps.addBatch();//执行批量插入操作ps.executeBatch();System.out.println("插入数据成功!");} catch (SQLException e) {System.out.println(e.getMessage());}}
}

其中,sql_str 中的两个问号(?)表示两个占位符,它们的值会在运行时进行替换;然后使用 prepareStatement()方法创建了一个预编译的 SQL 语句,在执行该语句之前使用 setString()和 setTimestamp() 方法替换占位符的值,并且使用 addBatch() 添加批量操作;最后执行
executeBatch()方法进行批量插入操作。

该程序的执行结果如下:

连接PostgreSQL数据库成功!
插入数据成功!

四、查询数据

通过JDBC 连接数据库并执行查询语句的过程如下:

  1. 利用 DriverManager 类的 getConnection()方法获取一个 Connection 连接对象;
  2. 使用连接对象的 createStatement()方法创建一个 Statement 或者PreparedStatement 语句对象;
  3. 利用语句对象的 executeQuery()方法执行 SQL 语句或者存储过程,返回一个 ResultSet 结果集对象;
  4. 遍历结果集,获取并处理查询结果;
  5. 释放 ResultSet、Statement 以及 Connection 对象资源。
package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class PostgreSQLQUery {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "select id, name, created_at" +" from users";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,创建查询语句,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql_str);//处理查询结果while (rs.next()) {System.out.println(rs.getInt("id") + "\t" +rs.getString("name") + "\t" +rs.getTimestamp("created_at"));}} catch (SQLException e) {System.out.println(e.getMessage());}}
}

首先,通过一个 FileInputStream 对象读取数据库的连接配置文件;然后使用try-with-resources方式建立数据库连接,创建查询语句,并且执行该语句;最后使用一个 while 循环获取查询结果集,rs.next()获取结果中的下一条记录;rs.getInt()、rs.getString()和 rs.getTimestamp()分别用于获取记录中的整数、字符串以及时间戳字段。

该程序的输出结果如下:

连接PostgreSQL数据库成功!
1	tony	2025-09-10 22:46:38.075
2	david	2025-09-10 22:46:38.076

五、修改数据

我们可以通过PreparedStatement 语句对象 executeUpdate()方法执行更新语句。创建一个新的
源文件 PostgreSQLUpdate.java:

package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class PostgreSQLUpdate {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "update users " +"set name = ? " +"where id = ?";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,创建查询语句,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");PreparedStatement ps = conn.prepareStatement(sql_str);//设置输入参数ps.setString(1, "tom");ps.setInt(2, 1);//执行更新操作int affectedrows = ps.executeUpdate();System.out.println(String.format("更新行数: %d", affectedrows));} catch (SQLException e) {System.out.println(e.getMessage());}}
}

其中,sql_str 中的两个问号(?)表示两个占位符,它们的值会在运行时进行替换;然后使用 prepareStatement()方法创建了一个 PreparedStatement 预编译的 SQL 语句,在执行该语句之前使用 setInt()和setString()方法替换占位符的值;最后执行 executeBatch()方法进行更新操作,返回
被更新的行数。

运行以上程序的输出结果如下:

连接PostgreSQL数据库成功!
更新行数: 1

六、删除数据

删除操作和插入、更新操作类似,只需要将 SQL 语句替换成 DELETE 即可。我们创建一个新的 Java 文件 PostgreSQLDelete.java:

package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;public class PostgreSQLDelete {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "delete from users " +"where id = ?";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,创建查询语句,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");PreparedStatement ps = conn.prepareStatement(sql_str);//设置输入参数ps.setInt(1, 1);//执行int affectedros = ps.executeUpdate();System.out.println(String.format("删除行数: %d", affectedros));} catch (SQLException e) {System.out.println(e.getMessage());}}
}

执行该程序输出的结果如下:

连接PostgreSQL数据库成功!
删除行数: 1

七、处理事务

默认情况下,JDBC 连接PostgreSQL 时使用自动提交模式,意味着每个 SQL 语句都会自动执行事务的提交操作。如果我们想要在一个事务中执行多条 SQL 语句,需要禁用连接对象的自动提交属性,并且手动执行 COMMIT 或者ROLLBACK 操作。

package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class PostgreSQLTransaction {public static void main(String[] args) {String url = null;String user = null;String password = null;String sql_str = "insert into users(name, created_at) " +"values(?, ?)";String sql_str2 = "update users set name = ? " +"where id = ?";//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,创建查询语句,并且执行语句try (Connection conn = DriverManager.getConnection(url, user, password)){System.out.println("连接PostgreSQL数据库成功!");//设置手动提交conn.setAutoCommit(false);try (PreparedStatement ps = conn.prepareStatement(sql_str);PreparedStatement ps2 = conn.prepareStatement(sql_str2)){//设置输入参数并执行语句ps.setString(1, "anne");ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));ps.executeUpdate();ps2.setString(1, "anne");ps2.setInt(2, 2);ps2.executeUpdate();//提交事务conn.commit();System.out.println("事务提交成功!");} catch (SQLException e) {//回滚事务conn.rollback();System.out.println(e.getMessage());System.out.println("回滚事务!");}} catch (SQLException e) {System.out.println(e.getMessage());}}
}

创建连接之后,使用 setAutoCommit()方法禁用自动提交;然后分别执行插入语句和更新语句,并提交事务;在异常处理中回滚事务并打印错误消息。

由于更新语句将 name 设置为重复值,因此该程序返回以下错误:

连接PostgreSQL数据库成功!
ERROR: duplicate key value violates unique constraint "users_name_key"详细:Key (name)=(anne) already exists.
回滚事务!

此时,插入语句也会被回滚;所以并不会创建 anne。

八、调用存储过程

利用 JDBC 中的 CallableStatement 对象可以调用 PostgreSQL 存储过程和函数。首先创建一个存储过程 add_user:

CREATE OR REPLACE PROCEDURE add_user(pv_name varchar, pd_created_at timestamp)
AS $$
BEGININSERT INTO users(name, created_at)VALUES (pv_name, pd_created_at);
END; $$
LANGUAGE plpgsql;

CallableStatement 对象默认只支持存储函数调用;为了支持存储过程,需要将连接属性escapeSyntaxCallMode 设置为 callIfNoReturn。我们将db.properties 文件修改如下:

url=jdbc:postgresql://192.168.56.104:5432/hrdb?escapeSyntaxCallMode=callI
fNoReturn
user=tony
password=tony
package demo;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class PostgreSQLSP {public static void main(String[] args) {String url = null;String user = null;String password = null;//读取数据库连接配置文件//加载properties文件try (InputStream input = App.class.getClassLoader().getResourceAsStream("db.properties")) {if (input == null) {System.out.println("未找到配置文件");return;}// 加载属性列表从输入流Properties pros = new Properties();pros.load(input);url = pros.getProperty("url");user = pros.getProperty("user");password = pros.getProperty("password");} catch (IOException e) {System.out.println(e.getMessage());}//建立数据库连接,调用存储过程try (Connection conn = DriverManager.getConnection(url, user, password);CallableStatement stmt = conn.prepareCall("{call add_user(?, ?)}")){stmt.setString(1, "anne");stmt.setTimestamp(2, new Timestamp(System.currentTimeMillis()));stmt.execute();System.out.println("调用存储过程成功!");} catch (SQLException e) {System.out.println(e.getMessage());}}
}

其中, **{ call add_user( ?, ? ) }**中的问号是占位符,表示一个输入参数;prepareCall()方法返回一个 CallableStatement 对象,代表调用存储过程的语句;设置输入参数后执行存储过程。

运行该程序输出以下内容:

调用存储过程成功!

文章转载自:

http://52aoXnV9.mrfjr.cn
http://rTZWZEGl.mrfjr.cn
http://pk8VNQ9S.mrfjr.cn
http://UQOQQWb7.mrfjr.cn
http://uG1glH3x.mrfjr.cn
http://RfKEybDC.mrfjr.cn
http://D5jTgadi.mrfjr.cn
http://uypSN7eL.mrfjr.cn
http://CD7BW5HT.mrfjr.cn
http://MxgR9Xxt.mrfjr.cn
http://Id4mDlsw.mrfjr.cn
http://RsqYXFpb.mrfjr.cn
http://1GWuNJKq.mrfjr.cn
http://UyNyKeD3.mrfjr.cn
http://Cj7jwIAZ.mrfjr.cn
http://pS5X6lwB.mrfjr.cn
http://dBDHkHlf.mrfjr.cn
http://6B38VtLB.mrfjr.cn
http://FwE0htcN.mrfjr.cn
http://E9o4gE1i.mrfjr.cn
http://L2EYO1eN.mrfjr.cn
http://PtThuxbB.mrfjr.cn
http://ktfYX5FN.mrfjr.cn
http://AMWbR5PY.mrfjr.cn
http://ndsS8VHT.mrfjr.cn
http://8bxzekKp.mrfjr.cn
http://QlNp0O8p.mrfjr.cn
http://JFuA3VOD.mrfjr.cn
http://VNC0XNft.mrfjr.cn
http://LGLXnu54.mrfjr.cn
http://www.dtcms.com/a/377491.html

相关文章:

  • Shell 函数详解
  • 【系统分析师】第21章-论文:系统分析师论文写作要点(核心总结)
  • Linux 命令(top/ps/netstat/vmstat/grep/sed/awk)及服务管理(systemd)
  • 【图像生成】提示词技巧
  • 揭秘Linux:开源多任务操作系统的强大基因
  • (ICLR-2025)深度压缩自动编码器用于高效高分辨率扩散模型
  • 《Why Language Models Hallucinate》论文解读
  • 【机器学习】通过tensorflow实现猫狗识别的深度学习进阶之路
  • AD5362BSTZ电子元器件 ADI 高精度数字模拟转换器DAC 集成电路IC
  • DMA-M2M存储器与存储器之间读写
  • Mistral Document AI已正式登陆Azure AI Foundry(国际版)
  • 机器学习实战(二):Pandas 特征工程与模型协同进阶
  • Flutter 朦胧效果布局大全:5种方法实现优雅视觉层次
  • 【CVPR2023】奔跑而非行走:追求更高FLOPS以实现更快神经网络
  • PHP学习(第三天)
  • 数仓简要笔记-1
  • 机器人商业化落地需要突破的关键性技术
  • AI 技术体系核心概念
  • STM32H750 I2C介绍及应用
  • 计算机网络---物理层
  • 【freemarker】创建html页面
  • 【华为OD】区块链文件转储系统
  • sprintf不是像printf一样的打印函数吗
  • Js 图片加载完成 与 图片缓存加载的区别
  • 汽车动力电池管理系统(BMS):电动汽车的“智能大脑”
  • n8n add npm module 發生 Module ‘ioredis‘ is disallowed,getaddrinfo EAI_AGAIN
  • 性能——day3
  • 安卓学习 之 SeekBar(音视频播放进度条)
  • CRMEB标准版PHP订单列表功能详解与优化技巧
  • Linux基础知识(五)