Introduction: Why Does a C++ Developer Need Databases?
C++ is one of the most powerful programming languages, used for creating high-load systems, games, financial applications, and embedded software. However, any serious application requires data storage. This is where database management systems (DBMS) come to the rescue.
In this article, we will explore how to connect to and perform basic operations with two popular DBMS — the relational PostgreSQL and the document-oriented MongoDB — using C++. The material is intended for beginner developers who are already familiar with the basics of C++ but have not yet worked with databases. You will learn how to install the necessary libraries, write simple CRUD queries, and avoid common mistakes.
1. Environment Setup and Library Selection
Before writing code, you need to install client libraries for working with databases. There are several options for C++, but we will look at the most popular and stable ones:
- For PostgreSQL —
libpqxx(official C++ wrapper over libpq). - For MongoDB —
mongocxx(official C++ driver from MongoDB).
Installing libpqxx (Ubuntu/Debian)
sudo apt-get updatesudo apt-get install libpqxx-devFor Windows or macOS, use the vcpkg or Homebrew package managers.
Installing mongocxx
First, install the base driver mongo-c-driver, then the C++ driver:
# Ubuntusudo apt-get install libmongoc-dev libbson-devsudo apt-get install libmongocxx-devAfter installation, make sure the compiler can see the header files. When compiling, do not forget to specify the linking flags:
g++ -std=c++17 main.cpp -lpqxx -lpq -lmongocxx -lbson2. Working with PostgreSQL in C++
PostgreSQL is a powerful object-relational DBMS. We will use the libpqxx library, which provides a convenient C++ interface.
Connecting to the Server and Creating a Table
First, let's write a simple program that connects to a local database and creates a users table:
#include <iostream>#include <pqxx/pqxx>
int main() { try { // Connecting to the "testdb" database as user "postgres" pqxx::connection conn("host=localhost dbname=testdb user=postgres password=secret"); if (conn.is_open()) { std::cout << "Connection to PostgreSQL successful!" << std::endl; }
// Creating a transaction pqxx::work txn(conn);
// SQL query to create a table txn.exec("CREATE TABLE IF NOT EXISTS users (" "id SERIAL PRIMARY KEY," "name VARCHAR(100) NOT NULL," "email VARCHAR(100) UNIQUE NOT NULL);");
txn.commit(); // Committing the changes std::cout << "Table users created." << std::endl;
} catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } return 0;}CRUD Operations: Inserting and Reading Data
Let's add a few records and perform a query:
pqxx::work txn(conn);
// Inserting datatxn.exec_params("INSERT INTO users (name, email) VALUES ($1, $2);", "Ivan Petrov", "ivan@example.com");txn.exec_params("INSERT INTO users (name, email) VALUES ($1, $2);", "Maria Smirnova", "maria@example.com");txn.commit();
// Reading datapqxx::nontransaction ntxn(conn);pqxx::result result = ntxn.exec("SELECT id, name, email FROM users;");
for (auto row : result) { std::cout << "ID: " << row[0].as<int>() << ", Name: " << row[1].as<std::string>() << ", Email: " <<