Connettersi a MySQL tramite un programma scritto in C++ è possibile utilizzando i driver messi a disposizione sul sito di MySQL.
Essi sono scaricabili da qui: http://www.mysql.com/products/connector/.

La compilazione dei sorgenti è relativamente semplice.
Posizionandoci sulla cartella dei sorgenti, creiamo i Makefile e utilizziamo make:

antonio@antonio-net:~$ cd Desktop/mysql-connector-c++-1.0.5/
antonio@antonio-net:~/Desktop/mysql-connector-c++-1.0.5/$ cmake .
antonio@antonio-net:~/Desktop/mysql-connector-c++-1.0.5/$ make clean
antonio@antonio-net:~/Desktop/mysql-connector-c++-1.0.5/$ make

ed infine make install oppure copiare la directory cppconn e le librerie in driver dove si vuole (ad esempio in /usr/local/include e /usr/local/lib, rispettivamente).

Le classi che utilizzeremo saranno:

Driver Consente la connessione al database
Connection Rappresenta la connessione al database
Statement Rappresenta una semplice query
PreparedStatement Rappresenta query con parametri settabili successivamente
ResultSet Rappresenta il valore di ritorno di una query
ResultSetMetaData Contiene i metadati relativi al resultset


Per i nosti esempi, creiamo un file my.sql:

drop database if exists test;
create database test;
use test;

create table persone(
	cod  varchar(16) primary key,
	name varchar(30) not null
);

insert into persone (cod, name)
values	('blabla1', 'Antonio'), ('blabla2', 'Mario'),
	('blabla3', 'Marco'), ('blabla4', 'Aldo'),
	('blabla5', 'Giovanni');

e utilizziamo il client di mysql per dare tale file in input:

mysql> \. /home/antonio/Desktop/my.sql
Query OK, 1 row affected (0,00 sec)

Query OK, 1 row affected (0,00 sec)

Database changed
Query OK, 0 rows affected (0,09 sec)

Query OK, 5 rows affected (0,00 sec)
Records: 5  Duplicates: 0  Warnings: 0

Il nostro primo esempio mostrerà come recuperare i dati dalla tabella persone ordinandoli per nome:

#include <string>
#include <iostream>

#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/exception.h>
#include <cppconn/statement.h>
#include <cppconn/resultset.h>
#include <cppconn/resultset_metadata.h>

using namespace std;

const string user = "root";
const string passwd = "secret";
const string database = "test";
const string dbhost = "tcp://127.0.0.1:3306";

int main()
{
	sql::Driver* driver;
	sql::Connection* connection;
	sql::Statement* stmt;
	sql::ResultSet* res;
	sql::ResultSetMetaData* res_md;
	string query =
		"SELECT cod, name FROM persone ORDER BY name";

	try
	{
		// stabiliamo la connesione e selez. il db
		driver = get_driver_instance();
		connection = driver->connect(dbhost, user, passwd);
		connection->setSchema(database);
		// creiamo uno statement
		stmt = connection->createStatement();
		// eseguiamo la query
		res = stmt->executeQuery(query);
		// otteniamo i metadati
		res_md = res->getMetaData();

		// contiamo le righe ottenute
		cout << ">> Presi "
			<< res->rowsCount()
			<< " record <<"
			<< endl << endl;

		// stampiamo i nomi dei campi
		for(int i = 1; i <= res_md->getColumnCount(); i++)
			cout << res_md->getColumnLabel(i) << "\t\t";
		cout << endl << endl;

		// fetch dei dati
		while(res->next())
		{
			for(int i = 1; i <= res_md->getColumnCount(); i++)
				cout << res->getString(i) << "\t\t";
			cout << endl;
		}

		// liberiamo le risorse
		delete res;
		delete stmt;
		connection->close();
		delete connection;
	}
	catch(sql::SQLException& e)
	{
		cout << e.what() << endl;
	}
}

Otterremo come output:

>> Presi 5 record <<

cod		name		

blabla4		Aldo
blabla1		Antonio
blabla5		Giovanni
blabla3		Marco
blabla2		Mario

Modifichiamo il nostro esempio per mostrare l’utilizzo della classe PreparedStatement:

#include <string>
#include <iostream>

#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/exception.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include <cppconn/resultset_metadata.h>

using namespace std;

const string user = "root";
const string passwd = "secret";
const string database = "test";
const string dbhost = "tcp://127.0.0.1:3306";

int main()
{
	sql::Driver* driver;
	sql::Connection* connection;
	sql::PreparedStatement* stmt;
	sql::ResultSet* res;
	sql::ResultSetMetaData* res_md;
	// query parametrica
	string query =
	  "SELECT cod, name from persone where name = ?";

	try
	{
		driver = get_driver_instance();
		connection = driver->connect(dbhost, user, passwd);
		connection->setSchema(database);

		string name;
		while(1) {
			cout << "[nome (quit per terminare)]<< ";
			getline(cin, name);

			if(name == "quit")
				break;

			// preparo lo statement
			stmt = connection->prepareStatement(query);
			// setto il valore
			stmt->setString(1, name);

			res = stmt->executeQuery();
			res_md = res->getMetaData();

			if(res->rowsCount() == 0)
			{
				cout << endl << endl
					<< ">> Nessun record trovato <<"
					<< endl << endl;
				continue;
			}			

			cout << endl << endl;
			for(int i = 1; i <= res_md->getColumnCount(); i++)
				cout << res_md->getColumnLabel(i) << "\t\t";
			cout << endl << endl;

			while(res->next())
			{
				for(int i = 1; i <= res_md->getColumnCount(); i++)
					cout << res->getString(i) << "\t\t";
				cout << endl;
			}
			cout << endl << endl;
		}

		delete res;
		delete stmt;
		connection->close();
		delete connection;
	}
	catch(sql::SQLException& e)
	{
		cout << e.what() << endl;
	}
}

Dopo esser stato eseguito, il programma chiederà in input un nome e lo cercherà all’interno del database, fino a che non digiteremo quit.
L’uso di un PreparedStatement rende la costruzione delle query più elegante e flessibile, oltre ad evitare le classiche SQL Injection.