PostgreSQL JDBC Driver allows Java programs to connect to a PostgreSQL database using standard, database independent Java code.
The PostgreSQL JDBC Driver (PgJDBC) is the official Java Database Connectivity (JDBC) driver for PostgreSQL. It provides full JDBC 4.2 compliance and extensive PostgreSQL-specific extensions, enabling Java applications to connect to and interact with PostgreSQL databases using standard database-independent Java code while also providing access to PostgreSQL's advanced features.
pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.5</version>
</dependency>implementation 'org.postgresql:postgresql:42.7.5'// Main driver class (automatically registered)
import org.postgresql.Driver;
// PostgreSQL-specific connection interface
import org.postgresql.PGConnection;
// DataSource implementations
import org.postgresql.ds.PGSimpleDataSource;
import org.postgresql.ds.PGConnectionPoolDataSource;
import org.postgresql.xa.PGXADataSource;
// Fastpath API (deprecated)
import org.postgresql.fastpath.Fastpath;
// Standard JDBC interfaces
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Array;
// Java utility classes
import java.util.Map;
// XA transaction support (for distributed transactions)
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import javax.transaction.xa.XAException;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BasicExample {
public static void main(String[] args) {
// Connection URL format: jdbc:postgresql://host:port/database
String url = "jdbc:postgresql://localhost:5432/mydb";
String user = "postgres";
String password = "secret";
// Connect to database
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// Execute a query
String sql = "SELECT id, name, email FROM users WHERE active = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setBoolean(1, true);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println(id + ": " + name + " <" + email + ">");
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}The PostgreSQL JDBC Driver is organized around several key architectural components:
Driver: The main entry point (org.postgresql.Driver) that implements java.sql.Driver. Automatically registers with DriverManager when the class is loaded.
Connection Management: Provides both DriverManager-based connections and DataSource implementations for pooled/XA scenarios. All connections implement the PGConnection interface with PostgreSQL-specific extensions.
Statement Execution: Full support for Statement, PreparedStatement, and CallableStatement with server-side and client-side prepared statement modes.
Type System: Comprehensive mapping between Java types and PostgreSQL types, including support for arrays, custom types, geometric types, JSON, and more.
The driver supports extensive configuration through:
Driver registration, connection URL formats, connection establishment, and connection properties.
/**
* Main JDBC driver class for PostgreSQL
*/
public class org.postgresql.Driver implements java.sql.Driver {
/**
* Attempts to make a database connection to the given URL
* @param url JDBC URL of the form jdbc:postgresql://host:port/database
* @param info Connection properties (user, password, etc.)
* @return A Connection object or null if URL is not accepted
*/
public Connection connect(String url, Properties info) throws SQLException;
/**
* Returns true if the driver can handle the given URL
* @param url JDBC URL to check
*/
public boolean acceptsURL(String url) throws SQLException;
/**
* Manually registers the driver with DriverManager
*/
public static void register() throws SQLException;
/**
* Deregisters the driver from DriverManager
*/
public static void deregister() throws SQLException;
}Connection pooling and XA-enabled DataSource implementations for enterprise applications.
/**
* Simple non-pooling DataSource implementation
*/
public class org.postgresql.ds.PGSimpleDataSource implements DataSource {
public Connection getConnection() throws SQLException;
public Connection getConnection(String user, String password) throws SQLException;
public void setServerName(String serverName);
public void setPortNumber(int portNumber);
public void setDatabaseName(String databaseName);
public void setUser(String user);
public void setPassword(String password);
}
/**
* ConnectionPoolDataSource for use with connection pool managers
*/
public class org.postgresql.ds.PGConnectionPoolDataSource
implements ConnectionPoolDataSource {
public PooledConnection getPooledConnection() throws SQLException;
public PooledConnection getPooledConnection(String user, String password)
throws SQLException;
}
/**
* XA-enabled DataSource for distributed transactions
*/
public class org.postgresql.xa.PGXADataSource implements XADataSource {
public XAConnection getXAConnection() throws SQLException;
public XAConnection getXAConnection(String user, String password)
throws SQLException;
}Executing SQL statements with support for prepared statements, callable statements, and batch operations.
/**
* PostgreSQL-specific extensions to Statement
*/
public interface org.postgresql.PGStatement extends Statement {
/** Represents positive infinity for date/timestamp values */
long DATE_POSITIVE_INFINITY = 9223372036825200000L;
/** Represents negative infinity for date/timestamp values */
long DATE_NEGATIVE_INFINITY = -9223372036832400000L;
/** Smaller positive infinity value for compatibility */
long DATE_POSITIVE_SMALLER_INFINITY = 185543533774800000L;
/** Smaller negative infinity value for compatibility */
long DATE_NEGATIVE_SMALLER_INFINITY = -185543533774800000L;
/**
* Returns the OID of the last inserted row
*/
long getLastOID() throws SQLException;
/**
* Sets the threshold for switching to server-side prepared statements
* @param threshold Number of executions before using server prepare (0 = always, negative = never)
*/
void setPrepareThreshold(int threshold);
/**
* Gets the current prepare threshold
*/
int getPrepareThreshold();
/**
* Enables or disables adaptive fetch size adjustment
*/
void setAdaptiveFetch(boolean adaptiveFetch);
/**
* Returns whether adaptive fetch is enabled
*/
boolean getAdaptiveFetch();
}Processing query results with support for scrollable cursors, updateable result sets, and type conversions.
/**
* PostgreSQL-specific ResultSet metadata extensions
*/
public interface org.postgresql.PGResultSetMetaData extends ResultSetMetaData {
/**
* Returns the underlying column name (before any aliasing)
*/
String getBaseColumnName(int column) throws SQLException;
/**
* Returns the underlying table name (before any aliasing)
*/
String getBaseTableName(int column) throws SQLException;
/**
* Returns the underlying schema name
*/
String getBaseSchemaName(int column) throws SQLException;
/**
* Returns the format of the column: 0 for text, 1 for binary
*/
int getFormat(int column) throws SQLException;
}Transaction control with savepoints, isolation levels, and automatic savepoint management.
/**
* Automatic savepoint behavior options
*/
public enum org.postgresql.jdbc.AutoSave {
/** Never use automatic savepoints */
NEVER,
/** Always create a savepoint before each query */
ALWAYS,
/** Create savepoints only when needed for error recovery */
CONSERVATIVE;
/**
* Returns the string value of this enum (lowercase)
* @return Lowercase string representation
*/
public String value();
/**
* Parses AutoSave from string value
* @param value String representation (case-insensitive)
* @return AutoSave enum value
*/
public static AutoSave of(String value);
}
// Transaction methods on PGConnection
public interface org.postgresql.PGConnection extends Connection {
/**
* Gets the current autosave configuration
*/
AutoSave getAutosave();
/**
* Sets the autosave configuration
* @param autoSave Autosave mode
*/
void setAutosave(AutoSave autoSave);
}High-performance bulk data transfer using PostgreSQL's COPY protocol.
/**
* Manager for PostgreSQL COPY operations
*/
public class org.postgresql.copy.CopyManager {
/**
* Starts a COPY FROM STDIN operation (loading data into database)
* @param sql COPY command (e.g., "COPY table FROM STDIN")
* @return CopyIn interface for writing data
*/
public CopyIn copyIn(String sql) throws SQLException;
/**
* Starts a COPY TO STDOUT operation (extracting data from database)
* @param sql COPY command (e.g., "COPY table TO STDOUT")
* @return CopyOut interface for reading data
*/
public CopyOut copyOut(String sql) throws SQLException;
/**
* Copies data from a Reader into the database
* @param sql COPY command
* @param from Reader providing data
* @return Number of rows loaded
*/
public long copyIn(String sql, Reader from) throws SQLException, IOException;
/**
* Copies data from database to a Writer
* @param sql COPY command
* @param to Writer to receive data
* @return Number of rows (for server 8.2+; -1 for older)
*/
public long copyOut(String sql, Writer to) throws SQLException, IOException;
}Streaming access to PostgreSQL Large Objects (LOBs/BLOBs).
/**
* Manager for PostgreSQL Large Objects
*/
public class org.postgresql.largeobject.LargeObjectManager {
/** Mode constant: open for reading */
public static final int READ = 0x00040000;
/** Mode constant: open for writing */
public static final int WRITE = 0x00020000;
/** Mode constant: open for reading and writing */
public static final int READWRITE = READ | WRITE;
/**
* Creates a new large object (deprecated, use createLO)
* @return OID of the created large object
* @deprecated As of 8.3, replaced by createLO()
*/
@Deprecated
public int create() throws SQLException;
/**
* Creates a new large object with default READWRITE mode
* @return OID of the created large object
*/
public long createLO() throws SQLException;
/**
* Creates a new large object with specified mode
* @param mode Access mode (READ, WRITE, or READWRITE)
* @return OID of the created large object
*/
public long createLO(int mode) throws SQLException;
/**
* Opens an existing large object
* @param oid OID of the large object
* @param mode Access mode (READ, WRITE, or READWRITE)
* @return LargeObject handle for I/O operations
*/
public LargeObject open(long oid, int mode) throws SQLException;
/**
* Deletes a large object
* @param oid OID of the large object to delete
*/
public void delete(long oid) throws SQLException;
}Support for PostgreSQL logical and physical replication protocols.
/**
* API for PostgreSQL replication protocol
* Available only when connection is opened with replication=database or replication=true
*/
public interface org.postgresql.replication.PGReplicationConnection {
/**
* Starts building a replication stream (logical or physical)
* @return Fluent builder for configuring replication stream
*/
ChainedStreamBuilder replicationStream();
/**
* Starts building a create replication slot command
* @return Fluent builder for creating replication slot
*/
ChainedCreateReplicationSlotBuilder createReplicationSlot();
/**
* Drops a replication slot
* @param slotName Name of the slot to drop
*/
void dropReplicationSlot(String slotName) throws SQLException;
}SSL socket factories and configuration for secure connections.
/**
* SSL connection modes
*/
public enum org.postgresql.jdbc.SslMode {
/** Do not use SSL */
DISABLE,
/** Try non-SSL first, fallback to SSL if server requires it */
ALLOW,
/** Try SSL first, fallback to non-SSL if server doesn't support it */
PREFER,
/** Require SSL, but don't verify server certificate */
REQUIRE,
/** Require SSL and verify server certificate against CA */
VERIFY_CA,
/** Require SSL and verify server certificate including hostname */
VERIFY_FULL;
/**
* Returns whether this mode requires an encrypted connection
* @return true if REQUIRE or higher (VERIFY_CA, VERIFY_FULL)
*/
public boolean requireEncryption();
/**
* Returns whether this mode verifies the server certificate
* @return true for VERIFY_CA or VERIFY_FULL
*/
public boolean verifyCertificate();
/**
* Returns whether this mode verifies the server hostname matches the certificate
* @return true only for VERIFY_FULL
*/
public boolean verifyPeerName();
/**
* Parses SSL mode from connection properties
* @param info Connection properties
* @return SslMode enum constant
* @throws PSQLException if sslmode value is invalid
*/
public static SslMode of(Properties info) throws PSQLException;
}
/**
* Default SSL factory supporting libpq-compatible certificate files
* Extends WrappedFactory to provide SSL socket creation
*/
public class org.postgresql.ssl.LibPQFactory extends WrappedFactory {
// Supports ~/.postgresql/ directory for certificates and keys
// - root.crt: trusted CA certificates
// - postgresql.crt: client certificate
// - postgresql.pk8: client private key (PKCS#8 format)
}Support for PostgreSQL data types including arrays, geometric types, JSON, hstore, and custom types.
/**
* Base class for PostgreSQL custom types
*/
public class org.postgresql.util.PGobject implements Serializable, Cloneable {
/**
* Sets the PostgreSQL type name
*/
public void setType(String type);
/**
* Gets the PostgreSQL type name
*/
public String getType();
/**
* Sets the value from its string representation
*/
public void setValue(String value) throws SQLException;
/**
* Gets the string representation of the value
*/
public String getValue();
/**
* Returns true if value is SQL NULL
*/
public boolean isNull();
}
// PostgreSQL geometric types
public class org.postgresql.geometric.PGpoint extends PGobject {
public double x;
public double y;
public PGpoint();
public PGpoint(double x, double y);
public PGpoint(String value) throws SQLException;
}
public class org.postgresql.geometric.PGbox extends PGobject {
public PGpoint[] point; // Array of 2 corner points
}
public class org.postgresql.geometric.PGcircle extends PGobject {
public PGpoint center;
public double radius;
}Notifications (LISTEN/NOTIFY), connection properties, utilities, and specialized features.
/**
* Represents a notification received via LISTEN/NOTIFY
*/
public interface org.postgresql.PGNotification {
/**
* Returns the notification channel name
*/
String getName();
/**
* Returns the process ID of the notifying backend
*/
int getPID();
/**
* Returns the notification payload (PostgreSQL 9.0+)
*/
String getParameter();
}
// Notification methods on PGConnection
public interface org.postgresql.PGConnection extends Connection {
/**
* Returns notifications received since last call
* @return Array of notifications or null if none
*/
PGNotification[] getNotifications() throws SQLException;
/**
* Returns notifications with timeout
* @param timeoutMillis 0 to block forever, >0 to wait up to specified milliseconds
* @return Array of notifications or null if none
*/
PGNotification[] getNotifications(int timeoutMillis) throws SQLException;
/**
* Returns the backend process ID for this connection
*/
int getBackendPID();
/**
* Cancels the currently executing query
*/
void cancelQuery() throws SQLException;
/**
* Escapes an identifier for safe use in SQL
*/
String escapeIdentifier(String identifier) throws SQLException;
/**
* Escapes a literal string for safe use in SQL
*/
String escapeLiteral(String literal) throws SQLException;
/**
* Returns the COPY API for the current connection
* @return CopyManager for COPY operations
*/
CopyManager getCopyAPI() throws SQLException;
/**
* Returns the LargeObject API for the current connection
* @return LargeObjectManager for large object operations
*/
LargeObjectManager getLargeObjectAPI() throws SQLException;
/**
* Returns the replication API for the current connection
* @return PGReplicationConnection for replication operations
*/
PGReplicationConnection getReplicationAPI();
/**
* Creates an Array object from the given type name and elements
* @param typeName PostgreSQL type name
* @param elements Array elements
* @return Array object
*/
Array createArrayOf(String typeName, Object elements) throws SQLException;
/**
* Adds a handler for PostgreSQL custom data types
* @param type PostgreSQL type name
* @param klass Class implementing PGobject
*/
void addDataType(String type, Class<? extends PGobject> klass) throws SQLException;
/**
* Adds a handler for PostgreSQL custom data types (deprecated)
* @param type PostgreSQL type name
* @param className Class name as string
* @deprecated As of 8.0, replaced by addDataType(String, Class). This method
* does not work correctly for registering classes that cannot be
* directly loaded by the JDBC driver's classloader.
*/
@Deprecated
void addDataType(String type, String className);
/**
* Returns the Fastpath API for this connection
* @return Fastpath API instance
* @throws SQLException if an error occurs
* @deprecated This API is somewhat obsolete. Use prepared statements with binary
* transmission of parameters for similar performance and greater functionality.
*/
@Deprecated
Fastpath getFastpathAPI() throws SQLException;
/**
* Sets the default statement reuse threshold for server-side prepare
* @param threshold Number of executions before using server prepare
*/
void setPrepareThreshold(int threshold);
/**
* Gets the default statement reuse threshold for server-side prepare
* @return Current threshold
*/
int getPrepareThreshold();
/**
* Sets the default fetch size for statements created from this connection
* @param fetchSize Default fetch size
*/
void setDefaultFetchSize(int fetchSize) throws SQLException;
/**
* Gets the default fetch size for statements created from this connection
* @return Current default fetch size
*/
int getDefaultFetchSize();
/**
* Returns the query execution mode for this connection
* @return Current query mode
*/
PreferQueryMode getPreferQueryMode();
/**
* Changes a user's password to the specified new password
* @param user Username of the database user
* @param newPassword New password (array will be zeroed after use)
* @param encryptionType Encryption type (null, "md5", or "scram-sha-256")
*/
void alterUserPassword(String user, char[] newPassword, String encryptionType) throws SQLException;
/**
* Returns current values of all parameters reported by the server
* @return Unmodifiable map of parameter names to values
*/
Map<String, String> getParameterStatuses();
/**
* Returns the value of a specific server parameter
* @param parameterName Parameter name (case-insensitive)
* @return Parameter value or null if not defined
*/
String getParameterStatus(String parameterName);
/**
* Enables or disables adaptive fetch for connection
* @param adaptiveFetch Desired state of adaptive fetch
*/
void setAdaptiveFetch(boolean adaptiveFetch);
/**
* Returns the state of adaptive fetch for connection
* @return True if adaptive fetch is enabled
*/
boolean getAdaptiveFetch();
}The driver supports extensive configuration through connection properties. Key properties include:
Properties can be set in the JDBC URL, Properties object, or via DataSource setters:
// In URL
String url = "jdbc:postgresql://localhost/db?user=postgres&ssl=true&sslmode=require";
// In Properties
Properties props = new Properties();
props.setProperty("user", "postgres");
props.setProperty("password", "secret");
props.setProperty("ssl", "true");
props.setProperty("sslmode", "require");
Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost/db", props);
// Via DataSource
PGSimpleDataSource ds = new PGSimpleDataSource();
ds.setServerName("localhost");
ds.setDatabaseName("db");
ds.setUser("postgres");
ds.setPassword("secret");
ds.setSsl(true);
ds.setSslMode("require");
Connection conn = ds.getConnection();PostgreSQL-specific exceptions provide detailed error information:
/**
* PostgreSQL-specific SQLException with server error details
*/
public class org.postgresql.util.PSQLException extends SQLException {
/**
* Returns detailed server error message with additional context
*/
public ServerErrorMessage getServerErrorMessage();
}
/**
* Detailed error/warning message from PostgreSQL server
*/
public class org.postgresql.util.ServerErrorMessage implements Serializable {
public String getSeverity();
public String getSQLState();
public String getMessage();
public String getDetail();
public String getHint();
public int getPosition();
public String getWhere();
public String getSchema();
public String getTable();
public String getColumn();
public String getDatatype();
public String getConstraint();
public String getFile();
public int getLine();
public String getRoutine();
public String getInternalQuery();
public int getInternalPosition();
}Standard JDBC type mappings plus PostgreSQL-specific types:
| PostgreSQL Type | Java Type | JDBC Type |
|---|---|---|
| boolean | boolean | BIT |
| smallint | short | SMALLINT |
| integer | int | INTEGER |
| bigint | long | BIGINT |
| real | float | REAL |
| double precision | double | DOUBLE |
| numeric, decimal | java.math.BigDecimal | NUMERIC |
| character, varchar, text | String | VARCHAR |
| bytea | byte[] | BINARY |
| date | java.sql.Date | DATE |
| time | java.sql.Time | TIME |
| timestamp | java.sql.Timestamp | TIMESTAMP |
| json, jsonb | org.postgresql.util.PGobject | OTHER |
| uuid | java.util.UUID | OTHER |
| array types | java.sql.Array | ARRAY |
| hstore | java.util.Map | OTHER |
| geometric types | org.postgresql.geometric.* | OTHER |
The driver supports multiple hosts for high availability and load balancing:
// Multiple hosts with automatic failover
String url = "jdbc:postgresql://host1:5432,host2:5432,host3:5432/database"
+ "?targetServerType=primary&loadBalanceHosts=true";Properties:
PreparedStatement for repeated queries. Set prepareThreshold to control when server-side prepare is used.addBatch() and executeBatch() for bulk inserts/updates.binaryTransfer=true (default) for better performance.CopyManager for bulk data loading/unloading (much faster than INSERT).Install with Tessl CLI
npx tessl i tessl/maven-org-postgresql--postgresql