Storing JSON Documents in PostgreSQL Using Java

PostgreSQL JSONB Columns in Java Applications

Database Schema Setup

Create a table with a JSONB column to store semi-structured data:

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content JSONB NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_documents_content ON documents USING GIN (content);

The GIN index enables efficient JSONB queries and operator usage.

JDBC Implementation

package com.example.storage;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.time.LocalDateTime;

public class DocumentRepository {
    
    private final String connectionUrl;
    private final String credentials;
    
    public DocumentRepository(String host, int port, String database, 
                              String user, String password) {
        this.connectionUrl = String.format(
            "jdbc:postgresql://%s:%d/%s", host, port, database);
        this.credentials = user + "/" + password;
    }
    
    public void persist(String payload) throws Exception {
        String sql = "INSERT INTO documents (content, created_at) VALUES (?, ?)";
        
        try (Connection link = DriverManager.getConnection(connectionUrl, 
                   credentials.split("/")[0], credentials.split("/")[1]);
             PreparedStatement stmt = link.prepareStatement(sql)) {
            
            stmt.setObject(1, payload);
            stmt.setTimestamp(2, Timestamp.valueOf(LocalDateTime.now()));
            stmt.executeUpdate();
        }
    }
    
    public static void main(String[] args) {
        DocumentRepository repo = new DocumentRepository(
            "localhost", 5432, "testdb", "admin", "secret");
        
        String json = """
            {
                "username": "bob",
                "metadata": {
                    "role": "admin",
                    "permissions": ["read", "write", "delete"]
                }
            }
            """;
        
        repo.persist(json);
    }
}

The setObject() method passes the JSON string directly to PostgreSQL's JSONB type. JDBC handles type conversion automatically.

Querying JSONB Data

public List<String> findByField(String key, String value) throws Exception {
    List<String> results = new ArrayList<>();
    String sql = "SELECT content FROM documents WHERE content ->> ? = ?";
    
    try (Connection link = DriverManager.getConnection(connectionUrl, 
               credentials.split("/")[0], credentials.split("/")[1])) {
        
        try (PreparedStatement stmt = link.prepareStatement(sql)) {
            stmt.setString(1, key);
            stmt.setString(2, value);
            
            try (ResultSet rs = stmt.executeQuery()) {
                while (rs.next()) {
                    results.add(rs.getString("content"));
                }
            }
        }
    }
    return results;
}

The ->> operator extracts a text value from the JSON document. Use -> for JSON object retrieval.

Batch Insert Operasions

public void batchPersist(List<String> documents) throws Exception {
    String sql = "INSERT INTO documents (content) VALUES (?)";
    
    try (Connection link = DriverManager.getConnection(connectionUrl, 
               credentials.split("/")[0], credentials.split("/")[1])) {
        link.setAutoCommit(false);
        
        try (PreparedStatement stmt = link.prepareStatement(sql)) {
            for (String doc : documents) {
                stmt.setObject(1, doc);
                stmt.addBatch();
            }
            stmt.executeBatch();
            link.commit();
        } catch (SQLException e) {
            link.rollback();
            throw e;
        }
    }
}

Batch operations significantly improve throughput when inserting multiple JSON documents.

Configuraton via Properties File

# database.properties
db.host=localhost
db.port=5432
db.name=application_db
db.user=app_user
db.password=encrypted_password
Properties props = new Properties();
props.load(new FileInputStream("database.properties"));

Repository repo = new Repository(
    props.getProperty("db.host"),
    Integer.parseInt(props.getProperty("db.port")),
    props.getProperty("db.name"),
    props.getProperty("db.user"),
    props.getProperty("db.password")
);

Externalizing database configuration prevents hardcoded credentials in source code.

Tags: java PostgreSQL JSONB JDBC database

Posted on Tue, 07 Jul 2026 17:30:52 +0000 by djdon11